﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область СлужебныйПрограммныйИнтерфейс

// Возвращает список всех свойств для объекта метаданных.
//
// Параметры:
//  ВидОбъектов - Строка - полное имя объекта метаданных;
//  ВидСвойств  - Строка - "ДополнительныеРеквизиты" или "ДополнительныеСведения" или "Метки".
//
// Возвращаемое значение:
//  ТаблицаЗначений - свойство, Наименование, ТипЗначения, ФорматСвойства.
//  Неопределено    - для указанного вида объекта нет набора свойств.
//
Функция СписокСвойствДляВидаОбъектов(ВидОбъектов, Знач ВидСвойств) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ
		|	НаборыСвойств.Ссылка КАК Ссылка,
		|	НаборыСвойств.ИмяПредопределенныхДанных КАК ИмяПредопределенныхДанных
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК НаборыСвойств
		|ГДЕ
		|	НаборыСвойств.Предопределенный";
	Выборка = Запрос.Выполнить().Выбрать();
	
	ИмяПредопределенныхДанных = СтрЗаменить(ВидОбъектов, ".", "_");
	НаборСсылка = Неопределено;
	
	Пока Выборка.Следующий() Цикл
		Если СтрНачинаетсяС(Выборка.ИмяПредопределенныхДанных, "Удалить") Тогда
			Продолжить;
		КонецЕсли;
		
		Если Выборка.ИмяПредопределенныхДанных = ИмяПредопределенныхДанных Тогда
			НаборСсылка = Выборка.Ссылка;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если НаборСсылка = Неопределено Тогда
		НаборСсылка = УправлениеСвойствами.НаборСвойствПоИмени(ИмяПредопределенныхДанных);
		Если НаборСсылка = Неопределено Тогда
			Возврат Неопределено;
		КонецЕсли;
	КонецЕсли;
	
	ТекстЗапроса = 
		"ВЫБРАТЬ
		|	ТаблицаСвойств.Свойство КАК Свойство,
		|	ТаблицаСвойств.Свойство.Наименование КАК Наименование,
		|	ТаблицаСвойств.Свойство.ТипЗначения КАК ТипЗначения,
		|	ТаблицаСвойств.Свойство.ФорматСвойства КАК ФорматСвойства
		|ИЗ
		|	&ТаблицаСвойств КАК ТаблицаСвойств
		|ГДЕ
		|	ТаблицаСвойств.Ссылка В ИЕРАРХИИ (&Ссылка)
		|	И ТаблицаСвойств.Свойство.ВидСвойств В (&ВидыСвойств)";
	
	ВидыСвойств = Новый Массив;
	Если ВидСвойств = "ДополнительныеРеквизиты" Тогда
		ПолноеИмяТаблицы = "Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты";
		ВидыСвойств.Добавить(Перечисления.ВидыСвойств.ПустаяСсылка());
		ВидыСвойств.Добавить(Перечисления.ВидыСвойств.ДополнительныеРеквизиты);
	ИначеЕсли ВидСвойств = "ДополнительныеСведения" Тогда
		ПолноеИмяТаблицы = "Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения";
		ВидыСвойств.Добавить(Перечисления.ВидыСвойств.ПустаяСсылка());
		ВидыСвойств.Добавить(Перечисления.ВидыСвойств.ДополнительныеСведения);
	ИначеЕсли ВидСвойств = "Метки" Тогда
		ПолноеИмяТаблицы = "Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты";
		ВидыСвойств.Добавить(Перечисления.ВидыСвойств.Метки);
	Иначе
		Возврат Неопределено;
	КонецЕсли;
	ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "&ТаблицаСвойств", ПолноеИмяТаблицы);
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("Ссылка", НаборСсылка);
	Запрос.УстановитьПараметр("ВидыСвойств", ВидыСвойств);
	
	Результат = Запрос.Выполнить().Выгрузить();
	Результат.Свернуть("Свойство,Наименование,ТипЗначения,ФорматСвойства");
	Результат.Сортировать("Наименование Возр");
	
	Возврат Результат;
	
КонецФункции

// Дополняет список колонки для загрузки данных колонками дополнительных реквизитов и свойств.
//
// Параметры:
//  МетаданныеСправочника	 - ОбъектМетаданных - метаданные справочника.
//  ИнформацияПоКолонкам	 - ТаблицаЗначений:
//     * Видимость - Булево
//     * ПредставлениеКолонки - Строка
//     * Синоним - Строка
//     * ОбязательнаДляЗаполнения - Булево
//     * Позиция - Число
//     * ИмяКолонки - Строка
//     * Примечание - Строка
//     * ТипКолонки - Произвольный
//     * Группа - Строка
//     * Родитель - Строка
//     * Ширина - Число
//
Процедура КолонкиДляЗагрузкиДанных(МетаданныеСправочника, ИнформацияПоКолонкам) Экспорт
	
	Если МетаданныеСправочника.ТабличныеЧасти.Найти("ДополнительныеРеквизиты") <> Неопределено Тогда
		
		Позиция = ИнформацияПоКолонкам.Количество() + 1;
		Свойства = УправлениеСвойствами.СвойстваОбъекта(Справочники[МетаданныеСправочника.Имя].ПустаяСсылка());
		
		ЗначенияСвойств = ДополнительныеЗначенияСвойства(Свойства);
		СоответствиеЗначений = Новый Соответствие;
		Для Каждого Строка Из ЗначенияСвойств Цикл
			Значение = СоответствиеЗначений[Строка.Свойство];
			Если Значение = Неопределено Тогда
				СоответствиеЗначений.Вставить(Строка.Свойство, ОбщегоНазначенияКлиентСервер.ЗначениеВМассиве(Строка.Ссылка));
			Иначе
				СоответствиеЗначений[Строка.Свойство].Добавить(Строка.Ссылка);
			КонецЕсли;
		КонецЦикла;
		
		ДополнительныеСведения = Новый Массив;
		Для каждого Свойство Из Свойства Цикл
			Если Не Свойство.ЭтоДополнительноеСведение Тогда
				
				ИмяКолонки = "ДополнительныйРеквизит_" 
					+ СтандартныеПодсистемыСервер.ПреобразоватьСтрокуВДопустимоеНаименованиеКолонки(Строка(Свойство));
				
				Если ИнформацияПоКолонкам.Найти(ИмяКолонки, "ИмяКолонки") <> Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				СтрокаИнфоПроКолонки = ИнформацияПоКолонкам.Добавить();
				СтрокаИнфоПроКолонки.ИмяКолонки               = ИмяКолонки;
				СтрокаИнфоПроКолонки.ПредставлениеКолонки     = Строка(Свойство);
				СтрокаИнфоПроКолонки.ТипКолонки               = Свойство.ТипЗначения;
				СтрокаИнфоПроКолонки.ОбязательнаДляЗаполнения = Свойство.ЗаполнятьОбязательно;
				СтрокаИнфоПроКолонки.Позиция                  = Позиция;
				СтрокаИнфоПроКолонки.Группа                   = НСтр("ru = 'Доп. реквизиты'");
				СтрокаИнфоПроКолонки.Видимость                = Истина;
				СтрокаИнфоПроКолонки.Примечание               = Строка(Свойство);
				СтрокаИнфоПроКолонки.Ширина                   = 30;
				Позиция = Позиция + 1;
				
				Значения = СоответствиеЗначений[Свойство];
				Если ТипЗнч(Значения) = Тип("Массив") И Значения.Количество() > 0 Тогда
					СтрокаИнфоПроКолонки.Примечание = СтрокаИнфоПроКолонки.Примечание  + Символы.ПС + НСтр("ru = 'Варианты значений:'") + Символы.ПС;
					Для каждого Значение Из Значения Цикл
						Код = ?(ЗначениеЗаполнено(Значение.Код), " (" + Значение.Код + ")", "");
						СтрокаИнфоПроКолонки.Примечание = СтрокаИнфоПроКолонки.Примечание + Значение.Наименование + Код +Символы.ПС;
					КонецЦикла;
				КонецЕсли;
			Иначе
				ДополнительныеСведения.Добавить(Свойство);
			КонецЕсли;
		КонецЦикла;
		
		Для каждого Свойство Из ДополнительныеСведения Цикл
			
			ИмяКолонки = "Свойство_"
				+ СтандартныеПодсистемыСервер.ПреобразоватьСтрокуВДопустимоеНаименованиеКолонки(Строка(Свойство));
			
			Если ИнформацияПоКолонкам.Найти(ИмяКолонки, "ИмяКолонки") <> Неопределено Тогда
				Продолжить;
			КонецЕсли;
			
			СтрокаИнфоПроКолонки = ИнформацияПоКолонкам.Добавить();
			СтрокаИнфоПроКолонки.ИмяКолонки               = ИмяКолонки;
			СтрокаИнфоПроКолонки.ПредставлениеКолонки     = Строка(Свойство);
			СтрокаИнфоПроКолонки.ТипКолонки               = Свойство.ТипЗначения;
			СтрокаИнфоПроКолонки.ОбязательнаДляЗаполнения = Свойство.ЗаполнятьОбязательно;
			СтрокаИнфоПроКолонки.Позиция                  = Позиция;
			СтрокаИнфоПроКолонки.Группа                   = НСтр("ru = 'Доп. свойства'");
			СтрокаИнфоПроКолонки.Видимость                = Истина;
			СтрокаИнфоПроКолонки.Примечание               = Строка(Свойство);
			СтрокаИнфоПроКолонки.Ширина                   = 30;
			Позиция = Позиция + 1;
			
			Значения = СоответствиеЗначений[Свойство];
			Если ТипЗнч(Значения) = Тип("Массив") И Значения.Количество() > 0 Тогда
				СтрокаИнфоПроКолонки.Примечание = СтрокаИнфоПроКолонки.Примечание  + Символы.ПС + НСтр("ru = 'Варианты значений:'") + Символы.ПС;
				Для каждого Значение Из Значения Цикл
					Код = ?(ЗначениеЗаполнено(Значение.Код), " (" + Значение.Код + ")", "");
					СтрокаИнфоПроКолонки.Примечание = СтрокаИнфоПроКолонки.Примечание + Значение.Наименование + Код +Символы.ПС;
				КонецЦикла;
			КонецЕсли;
			
		КонецЦикла;

	КонецЕсли;

КонецПроцедуры

Процедура ЗагрузитьЗначенияСвойствИзФайла(СсылкаНаОбъект, СтрокаТаблицы) Экспорт
	
	Свойства = Новый Соответствие();
	
	Если УправлениеСвойствами.ИспользоватьДопРеквизиты(СсылкаНаОбъект)
		 Или УправлениеСвойствами.ИспользоватьДопСведения(СсылкаНаОбъект) Тогда
			СписокСвойств = УправлениеСвойствами.СвойстваОбъекта(СсылкаНаОбъект);
			Для Каждого Свойство Из СписокСвойств Цикл
				Свойства.Вставить(Строка(Свойство), Свойство);
			КонецЦикла;
	КонецЕсли;
	
	ТаблицаСвойств = Новый ТаблицаЗначений;
	ТаблицаСвойств.Колонки.Добавить("Свойство");
	ТаблицаСвойств.Колонки.Добавить("Значение");
	
	Для Каждого Колонка Из СтрокаТаблицы.Владелец().Колонки Цикл
		
		Префикс = "";
		
		Если СтрНачинаетсяС(Колонка.Имя, "ДополнительныйРеквизит_") Тогда
			Префикс = "ДополнительныйРеквизит_";
		ИначеЕсли СтрНачинаетсяС(Колонка.Имя, "Свойство_") Тогда
			Префикс = "Свойство_";
		КонецЕсли;
		
		Если ПустаяСтрока(Префикс) Тогда
			Продолжить;
		КонецЕсли;
		
		ИмяСвойства = СокрЛП(СтандартныеПодсистемыСервер.ПреобразоватьАдаптированноеНаименованиеКолонкиВСтроку(Сред(Колонка.Имя, 
			СтрДлина(Префикс) + 1)));
		Свойство = Свойства.Получить(ИмяСвойства); // ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
		Если Свойство <> Неопределено Тогда
			НоваяСтрокаСвойств = ТаблицаСвойств.Добавить();
			НоваяСтрокаСвойств.Свойство = Свойство.Ссылка;
			НоваяСтрокаСвойств.Значение = СтрокаТаблицы[Колонка.Имя];
		КонецЕсли;
		
	КонецЦикла;
	
	Если ТаблицаСвойств.Количество() > 0 Тогда
		УправлениеСвойствами.ЗаписатьСвойстваУОбъекта(СсылкаНаОбъект, ТаблицаСвойств);
	КонецЕсли;

КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обработчики событий подсистем конфигурации.

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковОбновления.
Процедура ПриДобавленииОбработчиковОбновления(Обработчики) Экспорт
	
	Обработчик = Обработчики.Добавить();
	Обработчик.ОбщиеДанные = Истина;
	Обработчик.УправлениеОбработчиками = Истина;
	Обработчик.Версия = "*";
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.Процедура = "УправлениеСвойствамиСлужебный.ЗаполнитьОбработчикиРазделенныхДанных";
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "*";
	Обработчик.Процедура = "УправлениеСвойствамиСлужебный.СоздатьПредопределенныеНаборыСвойств";
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.НачальноеЗаполнение = Истина;
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "2.3.1.21";
	Обработчик.Процедура = "УправлениеСвойствамиСлужебный.УстановитьЗначениеПризнакаИспользуется";
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.НачальноеЗаполнение = Истина;
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "3.1.5.128";
	Обработчик.Идентификатор = Новый УникальныйИдентификатор("ecd6aad4-4b04-43be-82bc-cd4f563beb0b");
	Обработчик.Процедура = "ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ОбработатьДанныеДляПереходаНаНовуюВерсию";
	Обработчик.Комментарий = НСтр("ru = 'Заполняет уникальное имя и обновляет зависимости дополнительных реквизитов и сведений.
		|Редактирование дополнительных реквизитов и сведений будет недоступно до завершения обновления.'");
	Обработчик.РежимВыполнения = "Отложенно";
	Обработчик.ПроцедураЗаполненияДанныхОбновления = "ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ЗарегистрироватьДанныеКОбработкеДляПереходаНаНовуюВерсию";
	Обработчик.ЧитаемыеОбъекты    = "ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения";
	Обработчик.ИзменяемыеОбъекты  = "ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения";
	Обработчик.ПроцедураПроверки  = "ОбновлениеИнформационнойБазы.ДанныеОбновленыНаНовуюВерсиюПрограммы";
	Обработчик.БлокируемыеОбъекты = "ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения";
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
		Обработчик.ПриоритетыВыполнения = ОбновлениеИнформационнойБазы.ПриоритетыВыполненияОбработчика();
	
		НоваяСтрока = Обработчик.ПриоритетыВыполнения.Добавить();
		НоваяСтрока.Процедура = "МультиязычностьСервер.ОбработатьДанныеДляПереходаНаНовуюВерсию";
		НоваяСтрока.Порядок = "До";
	КонецЕсли;
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "3.1.7.53";
	Обработчик.РежимВыполнения = "Оперативно";
	Обработчик.Процедура = "УправлениеСвойствамиСлужебный.ОчиститьНеиспользуемыеНастройки";
	
	Обработчик = Обработчики.Добавить();
	Обработчик.Версия = "*";
	Обработчик.РежимВыполнения = "Отложенно";
	Обработчик.Идентификатор = Новый УникальныйИдентификатор("ee1168cd-6428-4980-9ee6-602812264cfa");
	Обработчик.Комментарий = НСтр("ru = 'Реструктуризация дополнительных реквизитов и сведений.
		|До завершения обработки дополнительные реквизиты и сведения некоторых документов
		|и справочников будут недоступны.'");
	Обработчик.Процедура = "Справочники.НаборыДополнительныхРеквизитовИСведений.ОбработатьНаборыСвойствДляПереходаНаНовуюВерсию";
	
КонецПроцедуры

// См. ОбновлениеИнформационнойБазыБСП.ПриДобавленииОбработчиковПереходаСДругойПрограммы.
Процедура ПриДобавленииОбработчиковПереходаСДругойПрограммы(Обработчики) Экспорт
	
	Обработчик = Обработчики.Добавить();
	Обработчик.ПредыдущееИмяКонфигурации = "*";
	Обработчик.Процедура = "УправлениеСвойствамиСлужебный.СоздатьПредопределенныеНаборыСвойств";
	
КонецПроцедуры

// См. ЗапретРедактированияРеквизитовОбъектовПереопределяемый.ПриОпределенииОбъектовСЗаблокированнымиРеквизитами.
Процедура ПриОпределенииОбъектовСЗаблокированнымиРеквизитами(Объекты) Экспорт
	Объекты.Вставить(Метаданные.ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПолноеИмя(), "");
КонецПроцедуры

// Смотри также ОбновлениеИнформационнойБазыПереопределяемый.ПриОпределенииНастроек
//
// Параметры:
//  Объекты - Массив из ОбъектМетаданных
//
Процедура ПриОпределенииОбъектовСНачальнымЗаполнением(Объекты) Экспорт
	
	Объекты.Добавить(Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений);
	
КонецПроцедуры

// См. ГрупповоеИзменениеОбъектовПереопределяемый.ПриОпределенииОбъектовСРедактируемымиРеквизитами.
Процедура ПриОпределенииОбъектовСРедактируемымиРеквизитами(Объекты) Экспорт
	Объекты.Вставить(Метаданные.ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке");
	Объекты.Вставить(Метаданные.Справочники.ЗначенияСвойствОбъектов.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке");
	Объекты.Вставить(Метаданные.Справочники.ЗначенияСвойствОбъектовИерархия.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке");
	Объекты.Вставить(Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений.ПолноеИмя(), "РеквизитыРедактируемыеВГрупповойОбработке");
КонецПроцедуры

// См. ВерсионированиеОбъектовПереопределяемый.ПриПодготовкеДанныхОбъекта
Процедура ПриПодготовкеДанныхОбъекта(Объект, ДополнительныеРеквизиты) Экспорт 
	
	ПолучатьДопРеквизиты = УправлениеСвойствами.ИспользоватьДопРеквизиты(Объект.Ссылка);
	ПолучатьДопСведения = УправлениеСвойствами.ИспользоватьДопСведения(Объект.Ссылка);
	
	Если ПолучатьДопРеквизиты Или ПолучатьДопСведения Тогда
		Для Каждого ЗначениеСвойства Из УправлениеСвойствами.ЗначенияСвойств(Объект.Ссылка, ПолучатьДопРеквизиты, ПолучатьДопСведения) Цикл
			Реквизит = ДополнительныеРеквизиты.Добавить();
			Реквизит.Наименование = ЗначениеСвойства.Свойство;
			Реквизит.Значение = ЗначениеСвойства.Значение;
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры

// См. ВерсионированиеОбъектовПереопределяемый.ПриВосстановленииВерсииОбъекта.
Процедура ПриВосстановленииВерсииОбъекта(Объект, ДополнительныеРеквизиты) Экспорт
	
	Для Каждого Реквизит Из ДополнительныеРеквизиты Цикл
		Если ТипЗнч(Реквизит.Наименование) = Тип("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения") Тогда
			ЭтоДополнительноеСведение = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Реквизит.Наименование, "ЭтоДополнительноеСведение");
			Если ЭтоДополнительноеСведение Тогда
				НаборЗаписей = РегистрыСведений.ДополнительныеСведения.СоздатьНаборЗаписей();
				НаборЗаписей.Отбор.Объект.Установить(Объект.Ссылка);
				НаборЗаписей.Отбор.Свойство.Установить(Реквизит.Наименование);
				
				Запись = НаборЗаписей.Добавить();
				Запись.Свойство = Реквизит.Наименование;
				Запись.Значение = Реквизит.Значение;
				Запись.Объект = Объект.Ссылка;
				НаборЗаписей.Записать();
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииИсключенийПоискаСсылок.
Процедура ПриДобавленииИсключенийПоискаСсылок(ИсключенияПоискаСсылок) Экспорт
	
	ИсключенияПоискаСсылок.Добавить(Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений.ПолноеИмя());
	ИсключенияПоискаСсылок.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.ТабличнаяЧасть.ЗависимостиДополнительныхРеквизитов.Реквизит.Значение");
	
КонецПроцедуры

// См. УправлениеДоступомПереопределяемый.ПриЗаполненииВидовДоступа.
Процедура ПриЗаполненииВидовДоступа(ВидыДоступа) Экспорт
	
	ВидДоступа = ВидыДоступа.Добавить();
	ВидДоступа.Имя = "ДополнительныеСведения";
	ВидДоступа.Представление = НСтр("ru = 'Дополнительные сведения'");
	ВидДоступа.ТипЗначений   = Тип("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения");
	
КонецПроцедуры

// См. УправлениеДоступомПереопределяемый.ПриЗаполненииСписковСОграничениемДоступа.
Процедура ПриЗаполненииСписковСОграничениемДоступа(Списки) Экспорт
	
	Списки.Вставить(Метаданные.Справочники.ЗначенияСвойствОбъектов, Истина);
	Списки.Вставить(Метаданные.Справочники.ЗначенияСвойствОбъектовИерархия, Истина);
	Списки.Вставить(Метаданные.ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения, Истина);
	Списки.Вставить(Метаданные.РегистрыСведений.ДополнительныеСведения, Истина);
	
КонецПроцедуры

// См. УправлениеДоступомПереопределяемый.ПриЗаполненииИспользованияВидаДоступа.
Процедура ПриЗаполненииИспользованияВидаДоступа(ВидДоступа, Использование) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если ВидДоступа = "ДополнительныеСведения" Тогда
		Использование = Константы.ИспользоватьДополнительныеРеквизитыИСведения.Получить();
	КонецЕсли;
	
КонецПроцедуры

// См. УправлениеДоступомПереопределяемый.ПриЗаполненииВидовОграниченийПравОбъектовМетаданных.
Процедура ПриЗаполненииВидовОграниченийПравОбъектовМетаданных(Описание) Экспорт
	
	Если НЕ ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		Возврат;
	КонецЕсли;
	
	МодульУправлениеДоступомСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступомСлужебный");
	
	Если МодульУправлениеДоступомСлужебный.ВидДоступаСуществует("ДополнительныеСведения") Тогда
		
		Описание = Описание + "
		|
		|Справочник.ЗначенияСвойствОбъектов.Чтение.ДополнительныеСведения
		|Справочник.ЗначенияСвойствОбъектовИерархия.Чтение.ДополнительныеСведения
		|ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Чтение.ДополнительныеСведения
		|РегистрСведений.ДополнительныеСведения.Чтение.ДополнительныеСведения
		|РегистрСведений.ДополнительныеСведения.Изменение.ДополнительныеСведения
		|";
	КонецЕсли;
	
КонецПроцедуры

// См. ОбщегоНазначенияПереопределяемый.ПриДобавленииОбработчиковУстановкиПараметровСеанса.
Процедура ПриДобавленииОбработчиковУстановкиПараметровСеанса(Обработчики) Экспорт
	Обработчики.Вставить("ИнтерактивнаяПроверкаЗаполненияСвойств", "УправлениеСвойствамиСлужебный.УстановкаПараметровСеанса");
КонецПроцедуры

// См. ОбщегоНазначенияПереопределяемый.ПриОпределенииПодчиненныхОбъектов
Процедура ПриОпределенииПодчиненныхОбъектов(ПодчиненныеОбъекты) Экспорт

	ПодчиненныйОбъект = ПодчиненныеОбъекты.Добавить();
	ПодчиненныйОбъект.ПодчиненныйОбъект = Метаданные.Справочники.ЗначенияСвойствОбъектов;
	ПодчиненныйОбъект.ПоляСвязей = "Владелец, Наименование";
	ПодчиненныйОбъект.ПриПоискеЗаменыСсылок = "УправлениеСвойствамиСлужебный";
	ПодчиненныйОбъект.ВыполнятьАвтоматическийПоискЗаменСсылок = Истина;
	
	ПодчиненныйОбъект = ПодчиненныеОбъекты.Добавить();
	ПодчиненныйОбъект.ПодчиненныйОбъект = Метаданные.Справочники.ЗначенияСвойствОбъектовИерархия;
	ПодчиненныйОбъект.ПоляСвязей = "Владелец, Наименование";
	ПодчиненныйОбъект.ПриПоискеЗаменыСсылок = "УправлениеСвойствамиСлужебный";
	ПодчиненныйОбъект.ВыполнятьАвтоматическийПоискЗаменСсылок = Истина;

КонецПроцедуры

// См. МультиязычностьСервер.ОбъектыСТЧПредставления
Процедура ПриОпределенииОбъектовСТабличнойЧастьюПредставление(Объекты) Экспорт
	Объекты.Добавить("Справочник.ЗначенияСвойствОбъектов");
	Объекты.Добавить("Справочник.ЗначенияСвойствОбъектовИерархия");
	Объекты.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
	Объекты.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения");
КонецПроцедуры

// АПК:299-выкл программно вызываемая процедур
//
// Вызывается при замене дублей в реквизитах элементов.
//
// Параметры:
//  ПарыЗамен - Соответствие - содержит пары значений оригинал и дубль.
//  НеобработанныеЗначенияОригиналов - Массив из Структура:
//    * ЗаменяемоеЗначение - ЛюбаяСсылка - оригинальное значение заменяемого объекта.
//    * ИспользуемыеСвязи - см. ОбщегоНазначения.СвязиПодчиненныхОбъектовПоТипам.
//    * ЗначениеКлючевыхРеквизитов - Структура - Ключ - имя реквизита, значение - значение реквизита.
//
Процедура ПриПоискеЗаменыСсылок(ПарыЗамен, НеобработанныеЗначенияОригиналов) Экспорт

	// Меняем владельца, если не нашли по наименованию похожего значения свойства
	Для каждого НеобработанныйДубль Из НеобработанныеЗначенияОригиналов Цикл
		
		НачатьТранзакцию();
		Попытка
		
			Блокировка = Новый БлокировкаДанных;
			Элемент = Блокировка.Добавить(НеобработанныйДубль.ЗаменяемоеЗначение.Метаданные().ПолноеИмя());
			Элемент.УстановитьЗначение("Ссылка",  НеобработанныйДубль.ЗаменяемоеЗначение);
			Блокировка.Заблокировать();
			
			НовоеЗначение = НеобработанныйДубль.ЗаменяемоеЗначение.ПолучитьОбъект();
			НовоеЗначение.ОбменДанными.Загрузка = Истина;
			НовоеЗначение.Владелец = НеобработанныйДубль.ЗначениеКлючевыхРеквизитов.Владелец;
			НовоеЗначение.Записать();
			ЗафиксироватьТранзакцию();
		
		Исключение
			
			ОтменитьТранзакцию();
			ЗаписьЖурналаРегистрации(НСтр("ru = 'Поиск и замена ссылок'", ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,
				НеобработанныйДубль.ЗаменяемоеЗначение.Метаданные(),,
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
			
		КонецПопытки;
			
	КонецЦикла;		

КонецПроцедуры
// АПК:299-вкл

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

Процедура ДополнительныеРеквизитыОбработкаПроверкиЗаполнения(Источник, Отказ, ПроверяемыеРеквизиты) Экспорт
	
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ПолучитьФункциональнуюОпцию("ИспользоватьДополнительныеРеквизитыИСведения") Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ПравоДоступа("Чтение", Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений) Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(Источник.Ссылка) = Тип("СправочникСсылка.НаборыДополнительныхРеквизитовИСведений") Тогда
		Возврат;
	КонецЕсли;
	
	Если ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияСвойств Тогда
		ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияСвойств = Ложь;
		Возврат;
	КонецЕсли;
	
	// Дополнительные реквизиты подключены к объекту.
	Проверка = Новый Структура;
	Проверка.Вставить("ДополнительныеРеквизиты", Неопределено);
	Проверка.Вставить("ЭтоГруппа", Ложь);
	ЗаполнитьЗначенияСвойств(Проверка, Источник);
	
	Если Проверка.ДополнительныеРеквизиты = Неопределено Тогда
		Возврат; // Быстрая проверка.
	КонецЕсли;
	
	ТабличнаяЧасть = Источник.Метаданные().ТабличныеЧасти.Найти("ДополнительныеРеквизиты");
	Если ТабличнаяЧасть = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ПроверкаТабличнойЧасти = Новый Структура;
	ПроверкаТабличнойЧасти.Вставить("Значение");
	ПроверкаТабличнойЧасти.Вставить("Свойство");
	ПроверкаТабличнойЧасти.Вставить("ТекстоваяСтрока");
	ЗаполнитьЗначенияСвойств(ПроверкаТабличнойЧасти, ТабличнаяЧасть.Реквизиты);
	Если ПроверкаТабличнойЧасти.Свойство = Неопределено
		Или ПроверкаТабличнойЧасти.Значение = Неопределено
		Или ПроверкаТабличнойЧасти.ТекстоваяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Проверка.ЭтоГруппа Тогда
		Возврат; // Для групп дополнительные реквизиты не подключаются.
	КонецЕсли;
	
	ЗаполненныеРеквизиты = Источник.ДополнительныеРеквизиты.ВыгрузитьКолонку("Свойство");
	
	ТаблицаНаборов = ПолучитьНаборыСвойствОбъекта(Источник);
	Наборы = ТаблицаНаборов.ВыгрузитьКолонку("Набор");
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Ссылки", Наборы);
	Запрос.УстановитьПараметр("ЗаполненныеРеквизиты", ЗаполненныеРеквизиты);
	Запрос.Текст =
		"ВЫБРАТЬ
		|	РеквизитыНабора.Свойство КАК Свойство
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК РеквизитыНабора
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизиты
		|		ПО РеквизитыНабора.Свойство = ДополнительныеРеквизиты.Ссылка
		|ГДЕ
		|	РеквизитыНабора.Ссылка В(&Ссылки)
		|	И НЕ РеквизитыНабора.ПометкаУдаления
		|	И НЕ ДополнительныеРеквизиты.ПометкаУдаления
		|	И ДополнительныеРеквизиты.ЗаполнятьОбязательно = ИСТИНА
		|	И НЕ РеквизитыНабора.Свойство В (&ЗаполненныеРеквизиты)";
	Результат = Запрос.Выполнить().Выгрузить();
	
	Если Результат.Количество() = 0 Тогда
		Возврат; // Нет обязательных для заполнения.
	КонецЕсли;
	Реквизиты = Результат.ВыгрузитьКолонку("Свойство");
	
	Сообщения = Новый Массив;
	
	Зависимости = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(Реквизиты, "ЗависимостиДополнительныхРеквизитов");
	Для Каждого Элемент Из Зависимости Цикл
		ТаблицаЗависимостей = Элемент.Значение.ЗависимостиДополнительныхРеквизитов.Выгрузить();
		Отбор = Новый Структура;
		Отбор.Вставить("ЗависимоеСвойство", "ЗаполнятьОбязательно");
		ЗависимостиОбязательностиЗаполнения = ТаблицаЗависимостей.НайтиСтроки(Отбор);
		Если ЗависимостиОбязательностиЗаполнения.Количество() = 0 Тогда
			Текст = НСтр("ru = 'Реквизит ""%1"" не заполнен.'");
			Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Текст, Элемент.Ключ);
			Сообщения.Добавить(Текст);
		Иначе
			// Нужно получить все реквизиты объекта на случай, если по ним настроена зависимость.
			ДополнительныеРеквизитыОбъекта = УправлениеСвойствами.СвойстваОбъекта(Источник, Истина, Ложь);
			ЗначенияРеквизитов = Новый Структура;
			Для Каждого ДополнительныйРеквизит Из ДополнительныеРеквизитыОбъекта Цикл
				Строка   = Проверка.ДополнительныеРеквизиты.Найти(ДополнительныйРеквизит, "Свойство");
				Свойства = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ДополнительныйРеквизит, "Имя,ТипЗначения");
				ИмяРеквизита = "_" + Свойства.Имя;
				Если Строка = Неопределено Тогда
					ЗначенияРеквизитов.Вставить(ИмяРеквизита, Свойства.ТипЗначения.ПривестиЗначение(Неопределено));
				Иначе
					ЗначенияРеквизитов.Вставить(ИмяРеквизита, Строка.Значение);
				КонецЕсли;
			КонецЦикла;
			
			ОписаниеЗависимогоРеквизита = Новый Структура;
			ОписаниеЗависимогоРеквизита.Вставить("УсловиеОбязательностиЗаполнения", Неопределено);
			Параметры = Неопределено;
			Для Каждого СтрокаЗависимостей Из ЗависимостиОбязательностиЗаполнения Цикл
				Если Наборы.Найти(СтрокаЗависимостей.НаборСвойств) = Неопределено Тогда
					Продолжить;
				КонецЕсли;
				
				Если ТипЗнч(СтрокаЗависимостей.Реквизит) = Тип("Строка") Тогда
					ПутьКРеквизиту = "Параметры.ОписаниеОбъекта." + СтрокаЗависимостей.Реквизит;
				Иначе
					ИмяРеквизита = "_" + ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СтрокаЗависимостей.Реквизит, "Имя");
					ПутьКРеквизиту = "Параметры.Форма." + ИмяРеквизита;
				КонецЕсли;
				
				ПостроитьУсловияЗависимостей(ОписаниеЗависимогоРеквизита, ПутьКРеквизиту, СтрокаЗависимостей);
				Параметры = ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения;
			КонецЦикла;
			
			Если Параметры = Неопределено Тогда
				НеобходимоЗаполнить = Истина;
			Иначе
				ПараметрыУсловия = Новый Структура;
				ПараметрыУсловия.Вставить("ЗначенияПараметров", Параметры.ЗначенияПараметров);
				ПараметрыУсловия.Вставить("Форма", ЗначенияРеквизитов);
				ПараметрыУсловия.Вставить("ОписаниеОбъекта", Источник);
				
				НеобходимоЗаполнить = ОбщегоНазначения.ВычислитьВБезопасномРежиме(Параметры.КодУсловия, ПараметрыУсловия);
			КонецЕсли;
			
			Если НеобходимоЗаполнить Тогда
				Текст = НСтр("ru = 'Реквизит ""%1"" не заполнен.'");
				Текст = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(Текст, Элемент.Ключ);
				Сообщения.Добавить(Текст);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Если Сообщения.Количество() > 0 Тогда
		ОбщегоНазначения.СообщитьПользователю(СтрСоединить(Сообщения, Символы.ПС), , , , Отказ);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//   ОписаниеЗависимогоРеквизита - Структура
//   ПутьКРеквизиту - Строка
//   СтрокаТаблицы - СтрокаТаблицыЗначений:
//      * ЗависимоеСвойство - Строка
//      * НаборСвойств - СправочникСсылка.НаборыДополнительныхРеквизитовИСведений
//      * Реквизит - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения
//      * Условие - Строка
//      * Значение - Строка
//                 - Число
//                 - Булево
//                 - Дата
//                 - ЛюбаяСсылка
//
Процедура ПостроитьУсловияЗависимостей(ОписаниеЗависимогоРеквизита, ПутьКРеквизиту, СтрокаТаблицы) Экспорт
	
	// Преобразование старого условия для обратной совместимости.
	УсловиеЧастями = СтрРазделить(СтрокаТаблицы.Условие, " ");
	НовоеУсловие = "";
	Если УсловиеЧастями.Количество() > 0 Тогда
		Для Каждого ЧастьУсловия Из УсловиеЧастями Цикл
			НовоеУсловие = НовоеУсловие + ВРег(Лев(ЧастьУсловия, 1)) + Сред(ЧастьУсловия, 2);
		КонецЦикла;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(НовоеУсловие) Тогда
		СтрокаТаблицы.Условие = НовоеУсловие;
	КонецЕсли;
	
	ШаблонУсловия = "";
	Если СтрокаТаблицы.Условие = "Равно" Тогда
		ШаблонУсловия = "%1 = %2";
	ИначеЕсли СтрокаТаблицы.Условие = "НеРавно" Тогда
		ШаблонУсловия = "%1 <> %2";
	КонецЕсли;
	
	Если СтрокаТаблицы.Условие = "ВСписке" Тогда
		ШаблонУсловия = "%2.НайтиПоЗначению(%1) <> Неопределено";
	ИначеЕсли СтрокаТаблицы.Условие = "НеВСписке" Тогда
		ШаблонУсловия = "%2.НайтиПоЗначению(%1) = Неопределено";
	КонецЕсли;
	
	ПравоеЗначение = "";
	Если ЗначениеЗаполнено(ШаблонУсловия) Тогда
		ПравоеЗначение = "Параметры.ЗначенияПараметров[""" + ПутьКРеквизиту + """]";
	КонецЕсли;
	
	Если СтрокаТаблицы.Условие = "Заполнено" Тогда
		ШаблонУсловия = "ЗначениеЗаполнено(%1)";
	ИначеЕсли СтрокаТаблицы.Условие = "НеЗаполнено" Тогда
		ШаблонУсловия = "Не ЗначениеЗаполнено(%1)";
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПравоеЗначение) Тогда
		КодУсловия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонУсловия, ПутьКРеквизиту, ПравоеЗначение);
	Иначе
		КодУсловия = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонУсловия, ПутьКРеквизиту);
	КонецЕсли;
	
	Если СтрокаТаблицы.ЗависимоеСвойство = "Доступен" Тогда
		УстановитьУсловиеЗависимости(ОписаниеЗависимогоРеквизита.УсловиеДоступности, ПутьКРеквизиту, СтрокаТаблицы, КодУсловия, СтрокаТаблицы.Условие);
	ИначеЕсли СтрокаТаблицы.ЗависимоеСвойство = "Виден" Тогда
		УстановитьУсловиеЗависимости(ОписаниеЗависимогоРеквизита.УсловиеВидимости, ПутьКРеквизиту, СтрокаТаблицы, КодУсловия, СтрокаТаблицы.Условие);
	Иначе
		УстановитьУсловиеЗависимости(ОписаниеЗависимогоРеквизита.УсловиеОбязательностиЗаполнения, ПутьКРеквизиту, СтрокаТаблицы, КодУсловия, СтрокаТаблицы.Условие);
	КонецЕсли;

КонецПроцедуры

Процедура УстановитьУсловиеЗависимости(СтруктураЗависимостей, ПутьКРеквизиту, СтрокаТаблицы, КодУсловия, Условие)
	Если СтруктураЗависимостей = Неопределено Тогда
		ЗначенияПараметров = Новый Соответствие;
		Если Условие = "ВСписке"
			Или Условие = "НеВСписке" Тогда
			Значение = Новый СписокЗначений;
			Значение.Добавить(СтрокаТаблицы.Значение);
		Иначе
			Значение = СтрокаТаблицы.Значение;
		КонецЕсли;
		ЗначенияПараметров.Вставить(ПутьКРеквизиту, Значение);
		СтруктураЗависимостей = Новый Структура;
		СтруктураЗависимостей.Вставить("КодУсловия", КодУсловия);
		СтруктураЗависимостей.Вставить("ЗначенияПараметров", ЗначенияПараметров);
	ИначеЕсли (Условие = "ВСписке" Или Условие = "НеВСписке")
		И ТипЗнч(СтруктураЗависимостей.ЗначенияПараметров[ПутьКРеквизиту]) = Тип("СписокЗначений") Тогда
		ЗначенияРеквизита = СтруктураЗависимостей.ЗначенияПараметров[ПутьКРеквизиту]; // СписокЗначений
		ЗначенияРеквизита.Добавить(СтрокаТаблицы.Значение);
	Иначе
		СтруктураЗависимостей.КодУсловия = СтруктураЗависимостей.КодУсловия + " И " + КодУсловия;
		Если Условие = "ВСписке" Или Условие = "НеВСписке" Тогда
			Значение = Новый СписокЗначений;
			Значение.Добавить(СтрокаТаблицы.Значение);
		Иначе
			Значение = СтрокаТаблицы.Значение;
		КонецЕсли;
		СтруктураЗависимостей.ЗначенияПараметров.Вставить(ПутьКРеквизиту, Значение);
	КонецЕсли;
КонецПроцедуры

// Параметры:
//  ИмяПараметра - Строка
//  УстановленныеПараметры - Массив из Строка
//
Процедура УстановкаПараметровСеанса(Знач ИмяПараметра, УстановленныеПараметры) Экспорт
	Если ИмяПараметра = "ИнтерактивнаяПроверкаЗаполненияСвойств" Тогда
		ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияСвойств = Ложь;
		УстановленныеПараметры.Добавить("ИнтерактивнаяПроверкаЗаполненияСвойств");
	КонецЕсли;
КонецПроцедуры

// См. УправлениеСвойствами.ПеренестиЗначенияИзРеквизитовФормыВОбъект.
Процедура ПеренестиЗначенияИзРеквизитовФормыВОбъект(Форма, Объект = Неопределено, ПередЗаписью = Ложь) Экспорт
	
	Приемник = Новый Структура;
	Приемник.Вставить("ПараметрыСвойств", Неопределено);
	ЗаполнитьЗначенияСвойств(Приемник, Форма);
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
		ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты
		ИЛИ (ТипЗнч(Приемник.ПараметрыСвойств) = Тип("Структура")
			И Приемник.ПараметрыСвойств.Свойство("ВыполненаОтложеннаяИнициализация")
			И Не Приемник.ПараметрыСвойств.ВыполненаОтложеннаяИнициализация) Тогда
		
		Возврат;
	КонецЕсли;
	
	Если Объект = Неопределено Тогда
		ОписаниеОбъекта = Форма.Объект;
	Иначе
		ОписаниеОбъекта = Объект;
	КонецЕсли;
	
	СтарыеЗначения = ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить();
	ДополнительныеРеквизиты = УправлениеСвойствами.СвойстваПоВидуДополнительныхРеквизитов(
		ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
		Перечисления.ВидыСвойств.ДополнительныеРеквизиты);
	Для каждого ДополнительныйРеквизит Из ДополнительныеРеквизиты Цикл
		Свойства = ОписаниеОбъекта.ДополнительныеРеквизиты.НайтиСтроки(
			Новый Структура("Свойство", ДополнительныйРеквизит));
		Для каждого Свойство Из Свойства Цикл
			ОписаниеОбъекта.ДополнительныеРеквизиты.Удалить(Свойство);
		КонецЦикла;
	КонецЦикла;
	
	Для каждого Строка Из Форма.Свойства_ОписаниеДополнительныхРеквизитов Цикл
		
		Значение = Форма[Строка.ИмяРеквизитаЗначение];
		
		Если Значение = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		Если Строка.ТипЗначения.Типы().Количество() = 1
		   И (НЕ ЗначениеЗаполнено(Значение) Или Значение = Ложь) Тогда
			
			Продолжить;
		КонецЕсли;
		
		Если Строка.Удалено Тогда
			Если ЗначениеЗаполнено(Значение) И Не (ПередЗаписью И Форма.Свойства_СкрытьУдаленные) Тогда
				НайденнаяСтрока = СтарыеЗначения.Найти(Строка.Свойство, "Свойство");
				Если НайденнаяСтрока <> Неопределено Тогда
					ЗаполнитьЗначенияСвойств(ОписаниеОбъекта.ДополнительныеРеквизиты.Добавить(), НайденнаяСтрока);
				КонецЕсли;
			КонецЕсли;
			Продолжить;
		КонецЕсли;
		
		// Поддержка строк гиперссылок.
		ИспользоватьСтрокуВВидеСсылки = ИспользоватьСтрокуВВидеСсылки(
			Строка.ТипЗначения, Строка.ВыводитьВВидеГиперссылки, Строка.МногострочноеПолеВвода);
		
		НоваяСтрока = ОписаниеОбъекта.ДополнительныеРеквизиты.Добавить();
		НоваяСтрока.Свойство = Строка.Свойство;
		Если ИспользоватьСтрокуВВидеСсылки Тогда
			АдресИПредставление = АдресИПредставление(Значение);
			НоваяСтрока.Значение = АдресИПредставление.Представление;
		Иначе
			НоваяСтрока.Значение = Значение;
		КонецЕсли;
		
		// Поддержка строк неограниченной длины.
		ИспользоватьНеограниченнуюСтроку = ИспользоватьНеограниченнуюСтроку(
			Строка.ТипЗначения, Строка.МногострочноеПолеВвода);
		
		Если ИспользоватьНеограниченнуюСтроку Или ИспользоватьСтрокуВВидеСсылки Тогда
			НоваяСтрока.ТекстоваяСтрока = Значение;
		КонецЕсли;
	КонецЦикла;
	
	Если ПередЗаписью Тогда
		Форма.Свойства_СкрытьУдаленные = Ложь;
	КонецЕсли;
	
КонецПроцедуры

Процедура ПеренестиУстановленныеМеткиВОбъект(Форма, Объект = Неопределено) Экспорт
	
	Если НЕ Форма.Свойства_ИспользоватьСвойства
		ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		Возврат;
	КонецЕсли;
	
	Если Объект = Неопределено Тогда
		ОписаниеОбъекта = Форма.Объект;
	Иначе
		ОписаниеОбъекта = Объект;
	КонецЕсли; 
	
	Метки = УправлениеСвойствами.СвойстваПоВидуДополнительныхРеквизитов(
		ОписаниеОбъекта.ДополнительныеРеквизиты.Выгрузить(),
		Перечисления.ВидыСвойств.Метки);
	Для каждого Метка Из Метки Цикл
		Свойства = ОписаниеОбъекта.ДополнительныеРеквизиты.НайтиСтроки(Новый Структура("Свойство", Метка));
		Для каждого Свойство Из Свойства Цикл
			ОписаниеОбъекта.ДополнительныеРеквизиты.Удалить(Свойство);
		КонецЦикла;
	КонецЦикла;
	
	Для каждого УстановленнаяМетка Из Форма.Свойства_УстановленныеМетки Цикл
		Метка = ОписаниеОбъекта.ДополнительныеРеквизиты.Добавить();
		Метка.Свойство = УстановленнаяМетка.Значение;
		Метка.Значение = Истина;
	КонецЦикла;
	
КонецПроцедуры

// Возвращает таблицу наборов доступных свойств владельца.
//
// Параметры:
//  ВладелецСвойств - ЛюбаяСсылка - ссылка на владельца свойств
//                  - СправочникОбъектИмяСправочника
//                  - ДокументОбъектИмяДокумента
//                  - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                  - БизнесПроцессОбъектИмяБизнесПроцесса
//                  - ЗадачаОбъектИмяЗадачи
//                  - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                  - ПланСчетовОбъектИмяПланаСчетов
//                  - ДанныеФормыСтруктура:
//                       * Ссылка - ЛюбаяСсылка
//  КлючНазначения - Строка
//
// Возвращаемое значение:
//   см. УправлениеСвойствамиПереопределяемый.ЗаполнитьНаборыСвойствОбъекта.НаборыСвойств
//
Функция ПолучитьНаборыСвойствОбъекта(Знач ВладелецСвойств, КлючНазначения = Неопределено) Экспорт
	
	Если ТипЗнч(ВладелецСвойств) = Тип("ДанныеФормыСтруктура") Тогда
		ТипСсылки = ТипЗнч(ВладелецСвойств.Ссылка);
	ИначеЕсли ОбщегоНазначения.ЭтоСсылка(ТипЗнч(ВладелецСвойств)) Тогда
		ТипСсылки = ТипЗнч(ВладелецСвойств);
	Иначе
		ТипСсылки = ТипЗнч(ВладелецСвойств.Ссылка)
	КонецЕсли;
	
	ПолучатьОсновнойНабор = Истина;
	
	НаборыСвойств = Новый ТаблицаЗначений;
	НаборыСвойств.Колонки.Добавить("Набор");
	НаборыСвойств.Колонки.Добавить("Высота");
	НаборыСвойств.Колонки.Добавить("Заголовок");
	НаборыСвойств.Колонки.Добавить("Подсказка");
	НаборыСвойств.Колонки.Добавить("РастягиватьПоВертикали");
	НаборыСвойств.Колонки.Добавить("РастягиватьПоГоризонтали");
	НаборыСвойств.Колонки.Добавить("ТолькоПросмотр");
	НаборыСвойств.Колонки.Добавить("ЦветТекстаЗаголовка");
	НаборыСвойств.Колонки.Добавить("Ширина");
	НаборыСвойств.Колонки.Добавить("ШрифтЗаголовка");
	НаборыСвойств.Колонки.Добавить("Группировка");
	НаборыСвойств.Колонки.Добавить("Отображение");
	НаборыСвойств.Колонки.Добавить("Картинка");
	НаборыСвойств.Колонки.Добавить("ОтображатьЗаголовок");
	НаборыСвойств.Колонки.Добавить("ОбщийНабор", Новый ОписаниеТипов("Булево"));
	// Устарело:
	НаборыСвойств.Колонки.Добавить("ШиринаПодчиненныхЭлементов");
	
	УправлениеСвойствамиПереопределяемый.ЗаполнитьНаборыСвойствОбъекта(
		ВладелецСвойств, ТипСсылки, НаборыСвойств, ПолучатьОсновнойНабор, КлючНазначения);
	
	Если НаборыСвойств.Количество() = 0
	   И ПолучатьОсновнойНабор = Истина Тогда
		
		ОсновнойНабор = ПолучитьОсновнойНаборСвойствДляОбъекта(ВладелецСвойств);
		
		Если ЗначениеЗаполнено(ОсновнойНабор) Тогда
			НаборыСвойств.Добавить().Набор = ОсновнойНабор;
		КонецЕсли;
	КонецЕсли;
	
	Возврат НаборыСвойств;
	
КонецФункции

// Возвращает заполненную таблицу значений свойств объекта.
// 
// Параметры:
//   ДополнительныеСвойстваОбъекта - ТаблицаЗначений
//   Наборы - ТаблицаЗначений
//   ВидСвойств - ПеречислениеСсылка.ВидыСвойств
//
Функция ЗначенияСвойств(ДополнительныеСвойстваОбъекта, Наборы, ВидСвойств) Экспорт
	
	Если ДополнительныеСвойстваОбъекта.Количество() = 0 Тогда
		// Предварительная быстрая проверка использования дополнительных свойств.
		СвойстваНеНайдены = ДополнительныеРеквизитыИСведенияНеНайдены(Наборы, ВидСвойств);
		
		Если СвойстваНеНайдены Тогда
			ОписаниеСвойств = Новый ТаблицаЗначений;
			ОписаниеСвойств.Колонки.Добавить("Набор");
			ОписаниеСвойств.Колонки.Добавить("Свойство");
			ОписаниеСвойств.Колонки.Добавить("ВладелецДополнительныхЗначений");
			ОписаниеСвойств.Колонки.Добавить("ЗаполнятьОбязательно");
			ОписаниеСвойств.Колонки.Добавить("Наименование");
			ОписаниеСвойств.Колонки.Добавить("ТипЗначения");
			ОписаниеСвойств.Колонки.Добавить("ФорматСвойства");
			ОписаниеСвойств.Колонки.Добавить("МногострочноеПолеВвода");
			ОписаниеСвойств.Колонки.Добавить("Удалено");
			ОписаниеСвойств.Колонки.Добавить("Значение");
			ОписаниеСвойств.Колонки.Добавить("НомерКартинки");
			Возврат ОписаниеСвойств;
		КонецЕсли;
	КонецЕсли;
	
	Свойства = ДополнительныеСвойстваОбъекта.ВыгрузитьКолонку("Свойство");
	
	НаборыСвойств = Новый ТаблицаЗначений;
	
	НаборыСвойств.Колонки.Добавить(
		"Набор", Новый ОписаниеТипов("СправочникСсылка.НаборыДополнительныхРеквизитовИСведений"));
	
	НаборыСвойств.Колонки.Добавить(
		"ПорядокНабора", Новый ОписаниеТипов("Число"));
	
	Для каждого ЭлементСписка Из Наборы Цикл
		НоваяСтрока = НаборыСвойств.Добавить();
		НоваяСтрока.Набор         = ЭлементСписка.Значение;
		НоваяСтрока.ПорядокНабора = Наборы.Индекс(ЭлементСписка);
	КонецЦикла;
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Свойства",      Свойства);
	Запрос.УстановитьПараметр("НаборыСвойств", НаборыСвойств);
	Запрос.УстановитьПараметр("ЭтоОсновнойЯзык", ОбщегоНазначения.ЭтоОсновнойЯзык());
	Запрос.УстановитьПараметр("КодЯзыка", ТекущийЯзык().КодЯзыка);
	Запрос.УстановитьПараметр("ВидСвойств", ВидСвойств);
	
	Запрос.Текст =
	"ВЫБРАТЬ
	|	НаборыСвойств.Набор КАК Набор,
	|	НаборыСвойств.ПорядокНабора КАК ПорядокНабора
	|ПОМЕСТИТЬ НаборыСвойств
	|ИЗ
	|	&НаборыСвойств КАК НаборыСвойств
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	НаборыСвойств.Набор КАК Набор,
	|	НаборыСвойств.ПорядокНабора КАК ПорядокНабора,
	|	СвойстваНаборов.Свойство КАК Свойство,
	|	СвойстваНаборов.ПометкаУдаления КАК ПометкаУдаления,
	|	СвойстваНаборов.НомерСтроки КАК ПорядокСвойства
	|ПОМЕСТИТЬ СвойстваНаборов
	|ИЗ
	|	НаборыСвойств КАК НаборыСвойств
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СвойстваНаборов
	|			ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
	|			ПО СвойстваНаборов.Свойство = Свойства.Ссылка
	|		ПО (СвойстваНаборов.Ссылка = НаборыСвойств.Набор)
	|ГДЕ
	|	НЕ СвойстваНаборов.ПометкаУдаления
	|	И НЕ Свойства.ПометкаУдаления
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	Свойства.Ссылка КАК Свойство
	|ПОМЕСТИТЬ ЗаполненныеСвойства
	|ИЗ
	|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
	|ГДЕ
	|	Свойства.Ссылка В(&Свойства)
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ
	|	СвойстваНаборов.Набор КАК Набор,
	|	СвойстваНаборов.ПорядокНабора КАК ПорядокНабора,
	|	СвойстваНаборов.Свойство КАК Свойство,
	|	СвойстваНаборов.ПорядокСвойства КАК ПорядокСвойства,
	|	СвойстваНаборов.ПометкаУдаления КАК Удалено
	|ПОМЕСТИТЬ ВсеСвойства
	|ИЗ
	|	СвойстваНаборов КАК СвойстваНаборов
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ЗНАЧЕНИЕ(Справочник.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка),
	|	0,
	|	ЗаполненныеСвойства.Свойство,
	|	0,
	|	ИСТИНА
	|ИЗ
	|	ЗаполненныеСвойства КАК ЗаполненныеСвойства
	|		ЛЕВОЕ СОЕДИНЕНИЕ СвойстваНаборов КАК СвойстваНаборов
	|		ПО ЗаполненныеСвойства.Свойство = СвойстваНаборов.Свойство
	|ГДЕ
	|	СвойстваНаборов.Свойство ЕСТЬ NULL
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗРЕШЕННЫЕ
	|	ВсеСвойства.Набор КАК Набор,
	|	ВсеСвойства.Свойство КАК Свойство,
	|	ДополнительныеРеквизитыИСведения.ВладелецДополнительныхЗначений КАК ВладелецДополнительныхЗначений,
	|	ДополнительныеРеквизитыИСведения.ЗаполнятьОбязательно КАК ЗаполнятьОбязательно,
	|	ДополнительныеРеквизитыИСведения.Заголовок КАК Наименование,
	|	ДополнительныеРеквизитыИСведения.ТипЗначения КАК ТипЗначения,
	|	ДополнительныеРеквизитыИСведения.ФорматСвойства КАК ФорматСвойства,
	|	ДополнительныеРеквизитыИСведения.МногострочноеПолеВвода КАК МногострочноеПолеВвода,
	|	ВсеСвойства.Удалено КАК Удалено,
	|	ДополнительныеРеквизитыИСведения.Доступен КАК Доступен,
	|	ДополнительныеРеквизитыИСведения.Виден КАК Виден,
	|	ДополнительныеРеквизитыИСведения.Подсказка КАК Подсказка,
	|	ДополнительныеРеквизитыИСведения.ВыводитьВВидеГиперссылки КАК ВыводитьВВидеГиперссылки,
	|	ДополнительныеРеквизитыИСведения.ЗависимостиДополнительныхРеквизитов.(
	|		ЗависимоеСвойство КАК ЗависимоеСвойство,
	|		Реквизит КАК Реквизит,
	|		Условие КАК Условие,
	|		Значение КАК Значение,
	|		НаборСвойств КАК НаборСвойств
	|	) КАК ЗависимостиДополнительныхРеквизитов,
	|	ВЫБОР
	|		КОГДА ДополнительныеРеквизитыИСведения.ПометкаУдаления = ИСТИНА
	|			ТОГДА 12
	|		КОГДА ДополнительныеРеквизитыИСведения.ВидСвойств = ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Метки)
	|			ТОГДА ДополнительныеРеквизитыИСведения.ЦветСвойств.Порядок + 1
	|		ИНАЧЕ 11
	|	КОНЕЦ КАК НомерКартинки
	|ИЗ
	|	ВсеСвойства КАК ВсеСвойства
	|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
	|		ПО ВсеСвойства.Свойство = ДополнительныеРеквизитыИСведения.Ссылка
	|ГДЕ
	|	ДополнительныеРеквизитыИСведения.ЭтоДополнительноеСведение = &ЭтоНаборыДополнительныхСведений
	|	И ДополнительныеРеквизитыИСведения.ВидСвойств В (ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.ПустаяСсылка), &ВидСвойств)
	|УПОРЯДОЧИТЬ ПО
	|	Удалено,
	|	ВсеСвойства.ПорядокНабора,
	|	ВсеСвойства.ПорядокСвойства";
	
	Если ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеСведения Тогда
		Запрос.Текст = СтрЗаменить(
			Запрос.Текст,
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты",
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения");
		ЭтоНаборыДополнительныхСведений = Истина;
	ИначеЕсли ВидСвойств = Перечисления.ВидыСвойств.Метки Тогда
		Запрос.Текст = СтрЗаменить(
			Запрос.Текст,
			"В (ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.ПустаяСсылка), &ВидСвойств)",
			"= ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Метки)");
		ЭтоНаборыДополнительныхСведений = Ложь;
	Иначе
		ЭтоНаборыДополнительныхСведений = Ложь;
	КонецЕсли;
	Запрос.УстановитьПараметр("ЭтоНаборыДополнительныхСведений", ЭтоНаборыДополнительныхСведений);
	
	СуффиксТекущегоЯзыка = ОбщегоНазначения.СуффиксЯзыкаТекущегоПользователя();
	Если СуффиксТекущегоЯзыка = Неопределено Тогда
		Запрос.Текст = СтрЗаменить(Запрос.Текст,
			"	ВсеСвойства КАК ВсеСвойства
			|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
			|		ПО ВсеСвойства.Свойство = ДополнительныеРеквизитыИСведения.Ссылка",
			"	ВсеСвойства КАК ВсеСвойства
			|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК ДополнительныеРеквизитыИСведения
			|		ПО ВсеСвойства.Свойство = ДополнительныеРеквизитыИСведения.Ссылка
			|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Представления КАК СвойстваПредставления
			|		ПО (СвойстваПредставления.Ссылка = ДополнительныеРеквизитыИСведения.Ссылка)
			|			И (СвойстваПредставления.КодЯзыка = &КодЯзыка)");
			
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "ДополнительныеРеквизитыИСведения.Заголовок КАК Наименование",
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.Заголовок, ДополнительныеРеквизитыИСведения.Заголовок) КАК СТРОКА(150)) КАК Наименование");
		
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "ДополнительныеРеквизитыИСведения.Подсказка КАК Подсказка",
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.Подсказка, ДополнительныеРеквизитыИСведения.Подсказка) КАК СТРОКА(150)) КАК Подсказка");
			
	Иначе
		
		Если ЗначениеЗаполнено(СуффиксТекущегоЯзыка) И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
			МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер");
			МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "ДополнительныеРеквизитыИСведения.Заголовок КАК Наименование");
			МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "ДополнительныеРеквизитыИСведения.Подсказка КАК Подсказка");
		КонецЕсли;
		
	КонецЕсли;
	
	ОписаниеСвойств = Запрос.Выполнить().Выгрузить();
	ОписаниеСвойств.Индексы.Добавить("Свойство");
	ОписаниеСвойств.Колонки.Добавить("Значение");
	
	// Удаление дублей свойств в нижестоящих наборах свойств.
	Если Наборы.Количество() > 1 Тогда
		Индекс = ОписаниеСвойств.Количество()-1;
		
		Пока Индекс >= 0 Цикл
			Строка = ОписаниеСвойств[Индекс];
			НайденнаяСтрока = ОписаниеСвойств.Найти(Строка.Свойство, "Свойство");
			
			Если НайденнаяСтрока <> Неопределено
			   И НайденнаяСтрока <> Строка Тогда
				
				ОписаниеСвойств.Удалить(Индекс);
			КонецЕсли;
			
			Индекс = Индекс-1;
		КонецЦикла;
	КонецЕсли;
	
	// Заполнение значений свойств.
	Для Каждого Строка Из ДополнительныеСвойстваОбъекта Цикл
		ОписаниеСвойства = ОписаниеСвойств.Найти(Строка.Свойство, "Свойство");
		Если ОписаниеСвойства <> Неопределено Тогда
			// Поддержка строк неограниченной длины.
			Если ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеРеквизиты Тогда
				ИспользоватьСтрокуВВидеСсылки = ИспользоватьСтрокуВВидеСсылки(
					ОписаниеСвойства.ТипЗначения,
					ОписаниеСвойства.ВыводитьВВидеГиперссылки,
					ОписаниеСвойства.МногострочноеПолеВвода);
				ИспользоватьНеограниченнуюСтроку = ИспользоватьНеограниченнуюСтроку(
					ОписаниеСвойства.ТипЗначения,
					ОписаниеСвойства.МногострочноеПолеВвода);
				НеобходимоПеренестиЗначениеИзСсылки = НеобходимоПеренестиЗначениеИзСсылки(
						Строка.ТекстоваяСтрока,
						Строка.Значение);
				Если (ИспользоватьНеограниченнуюСтроку
						Или ИспользоватьСтрокуВВидеСсылки
						Или НеобходимоПеренестиЗначениеИзСсылки)
					И НЕ ПустаяСтрока(Строка.ТекстоваяСтрока) Тогда
					Если Не ИспользоватьСтрокуВВидеСсылки И НеобходимоПеренестиЗначениеИзСсылки Тогда
						ЗначениеБезСсылки = ЗначениеБезСсылки(Строка.ТекстоваяСтрока, Строка.Значение);
						ОписаниеСвойства.Значение = ЗначениеБезСсылки;
					Иначе
						ОписаниеСвойства.Значение = Строка.ТекстоваяСтрока;
					КонецЕсли;
				Иначе
					ОписаниеСвойства.Значение = Строка.Значение;
				КонецЕсли;
			Иначе
				ОписаниеСвойства.Значение = Строка.Значение;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Возврат ОписаниеСвойств;
	
КонецФункции

// Только для внутреннего использования.
//
Функция ДополнительныеРеквизитыИСведенияНеНайдены(Наборы, ВидСвойств, ОтложеннаяИнициализация = Ложь)
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("НаборыСвойств", Наборы.ВыгрузитьЗначения());
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	СвойстваНаборов.Свойство КАК Свойство
	|ИЗ
	|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СвойстваНаборов
	|ГДЕ
	|	СвойстваНаборов.Ссылка В(&НаборыСвойств)
	|	И НЕ СвойстваНаборов.ПометкаУдаления";
	
	Если ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеСведения Тогда
		Запрос.Текст = СтрЗаменить(
			Запрос.Текст,
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты",
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения");
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	СвойстваНеНайдены = Запрос.Выполнить().Пустой();
	УстановитьПривилегированныйРежим(Ложь);
	
	Возврат СвойстваНеНайдены;
КонецФункции

Функция ОтображатьЗакладкуДополнительно(Ссылка, Наборы) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Ссылка", Ссылка);
	Запрос.УстановитьПараметр("НаборыСвойств", Наборы.ВыгрузитьЗначения());
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	ДополнительныеРеквизиты.Свойство КАК Свойство
		|ИЗ
		|	&ИмяТаблицы КАК ДополнительныеРеквизиты
		|ГДЕ
		|	ДополнительныеРеквизиты.Ссылка = &Ссылка
		|;
		|
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	СвойстваНаборов.Свойство КАК Свойство
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СвойстваНаборов
		|ГДЕ
		|	СвойстваНаборов.Ссылка В(&НаборыСвойств)
		|	И НЕ СвойстваНаборов.ПометкаУдаления";
	Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ИмяТаблицы", Ссылка.Метаданные().ПолноеИмя() + ".ДополнительныеРеквизиты");
	Результат = Запрос.ВыполнитьПакет();
	
	Возврат Не (Результат[0].Пустой() И Результат[1].Пустой());
	
КонецФункции

// Возвращает объект метаданных, который является владельцем значений
// свойств набора дополнительных реквизитов и сведений.
// 
// Параметры:
//  Ссылка - ЛюбаяСсылка
//
Функция МетаданныеВладельцаЗначенийСвойствНабора(Ссылка, УчитыватьПометкуУдаления = Истина, ТипСсылки = Неопределено) Экспорт
	
	Если НЕ ЗначениеЗаполнено(Ссылка) Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ПредопределенныеНаборыСвойств = УправлениеСвойствамиПовтИсп.ПредопределенныеНаборыСвойств();
	
	Если ТипЗнч(Ссылка) = Тип("Структура") Тогда
		СвойстваСсылки = Ссылка;
	Иначе
		СвойстваСсылки = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
			Ссылка, "ПометкаУдаления, ЭтоГруппа, Предопределенный, Родитель, ИмяПредопределенныхДанных, ИмяПредопределенногоНабора");
	КонецЕсли;
	
	Если ЗначениеЗаполнено(СвойстваСсылки.ИмяПредопределенногоНабора) Тогда
		СвойстваСсылки.ИмяПредопределенныхДанных = СвойстваСсылки.ИмяПредопределенногоНабора;
		СвойстваСсылки.Предопределенный          = Истина;
	КонецЕсли;
	
	Если УчитыватьПометкуУдаления И СвойстваСсылки.ПометкаУдаления Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Если СвойстваСсылки.ЭтоГруппа Тогда
		СсылкаПредопределенного = Ссылка;
		
	ИначеЕсли СвойстваСсылки.Предопределенный
	        И СвойстваСсылки.Родитель = Справочники.НаборыДополнительныхРеквизитовИСведений.ПустаяСсылка()
	        Или СвойстваСсылки.Родитель = Неопределено Тогда
		
		СсылкаПредопределенного = Ссылка;
	Иначе
		СсылкаПредопределенного = СвойстваСсылки.Родитель;
	КонецЕсли;
	
	Если Ссылка <> СсылкаПредопределенного Тогда
		СвойстваНабора = ПредопределенныеНаборыСвойств.Получить(СвойстваСсылки.Родитель);
		Если СвойстваНабора <> Неопределено Тогда
			СвойстваНабора = ПредопределенныеНаборыСвойств.Получить(СсылкаПредопределенного);// см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
			ИмяПредопределенного = СвойстваНабора.Имя;
		Иначе
			ИмяПредопределенного = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаПредопределенного, "ИмяПредопределенныхДанных");
		КонецЕсли;
	Иначе
		ИмяПредопределенного = СвойстваСсылки.ИмяПредопределенныхДанных;
	КонецЕсли;
	
	Позиция = СтрНайти(ИмяПредопределенного, "_");
	
	ПерваяЧастьИмени =  Лев(ИмяПредопределенного, Позиция - 1);
	ВтораяЧастьИмени = Прав(ИмяПредопределенного, СтрДлина(ИмяПредопределенного) - Позиция);
	
	ПолноеИмяТаблицы = ПерваяЧастьИмени + "." + ВтораяЧастьИмени;
	МетаданныеВладельца = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ПолноеИмяТаблицы);
	
	Если МетаданныеВладельца <> Неопределено Тогда
		ТипСсылки = Тип(ПерваяЧастьИмени + "Ссылка." + ВтораяЧастьИмени);
	КонецЕсли;
	
	Возврат МетаданныеВладельца;
	
КонецФункции

// Возвращает использование набором дополнительных реквизитов и сведений.
Функция ВидыСвойствНабора(Ссылка, УчитыватьПометкуУдаления = Истина) Экспорт
	
	ВидыСвойствНабора = УправлениеСвойствамиПовтИсп.ВидыСвойствНабора(Ссылка, УчитыватьПометкуУдаления);
	Возврат ВидыСвойствНабора;
	
КонецФункции

// Параметры:
//  ВсеНаборы см. УправлениеСвойствамиПереопределяемый.ЗаполнитьНаборыСвойствОбъекта.НаборыСвойств
//  НаборыСРеквизитами - СписокЗначений
//
Процедура ЗаполнитьНаборыСДополнительнымиРеквизитами(ВсеНаборы, НаборыСРеквизитами) Экспорт
	
	Ссылки = ВсеНаборы.ВыгрузитьКолонку("Набор");
	ИсключитьБитыеНаборыСвойств(Ссылки, Неопределено);
	ИсключитьБитыеНаборыСвойств(Ссылки, Null);
	
	СвойстваСсылок = ОбщегоНазначения.ЗначенияРеквизитовОбъектов(
		Ссылки, "ПометкаУдаления, ЭтоГруппа, Предопределенный, Родитель, ИмяПредопределенныхДанных, ИмяПредопределенногоНабора");
	
	Для Каждого СвойстваСсылки Из СвойстваСсылок Цикл
		ТипСсылки = Неопределено;
		МетаданныеВладельца = МетаданныеВладельцаЗначенийСвойствНабора(СвойстваСсылки.Значение, Истина, ТипСсылки);
		
		Если МетаданныеВладельца = Неопределено Тогда
			Возврат;
		КонецЕсли;
		
		// Проверка использования дополнительных реквизитов.
		Если МетаданныеВладельца.ТабличныеЧасти.Найти("ДополнительныеРеквизиты") <> Неопределено Тогда
			Строка = ВсеНаборы.Найти(СвойстваСсылки.Ключ, "Набор");
			НаборыСРеквизитами.Добавить(Строка.Набор, Строка.Заголовок);
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ИсключитьБитыеНаборыСвойств(Ссылки, Значение)
	
	Индекс = Ссылки.Найти(Значение);
	Пока Индекс <> Неопределено Цикл
		Ссылки.Удалить(Индекс);
		Индекс = Ссылки.Найти(Значение);
	КонецЦикла;
	
КонецПроцедуры

// Определяет, что тип значения содержит тип дополнительных значений свойств.
Функция ТипЗначенияСодержитЗначенияСвойств(ТипЗначения) Экспорт
	
	Возврат ТипЗначения.СодержитТип(Тип("СправочникСсылка.ЗначенияСвойствОбъектов"))
	    ИЛИ ТипЗначения.СодержитТип(Тип("СправочникСсылка.ЗначенияСвойствОбъектовИерархия"));
	
КонецФункции

// Проверяет возможность использования для свойства строки неограниченный длины.
Функция ИспользоватьНеограниченнуюСтроку(ТипЗначенияСвойства, МногострочноеПолеВвода) Экспорт
	
	Если ТипЗначенияСвойства.СодержитТип(Тип("Строка"))
	   И ТипЗначенияСвойства.Типы().Количество() = 1
	   И (ТипЗначенияСвойства.КвалификаторыСтроки.Длина = 0
		   Или МногострочноеПолеВвода > 1) Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли;
	
КонецФункции

Функция ИспользоватьСтрокуВВидеСсылки(ТипЗначенияСвойства, ВыводитьВВидеГиперссылки, МногострочноеПолеВвода)
	СписокТипов = ТипЗначенияСвойства.Типы();
	
	Если Не ИспользоватьНеограниченнуюСтроку(ТипЗначенияСвойства, МногострочноеПолеВвода)
		И СписокТипов.Количество() = 1
		И СписокТипов[0] = Тип("Строка")
		И ВыводитьВВидеГиперссылки Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли;
	
КонецФункции

Функция АдресИПредставление(Строка) Экспорт
	
	Результат = Новый Структура;
	НачалоВыделения = СтрНайти(Строка, "<a href = ");
	
	СтрокаПослеОткрывающегоТега = Сред(Строка, НачалоВыделения + 9);
	ЗакрывающийТег = СтрНайти(СтрокаПослеОткрывающегоТега, ">");
	
	Ссылка = СокрЛП(Лев(СтрокаПослеОткрывающегоТега, ЗакрывающийТег - 2));
	Если СтрНачинаетсяС(Ссылка, """") Тогда
		Ссылка = Сред(Ссылка, 2, СтрДлина(Ссылка) - 1);
	КонецЕсли;
	Если СтрЗаканчиваетсяНа(Ссылка, """") Тогда
		Ссылка = Сред(Ссылка, 1, СтрДлина(Ссылка) - 1);
	КонецЕсли;
	
	СтрокаПослеСсылки = Сред(СтрокаПослеОткрывающегоТега, ЗакрывающийТег + 1);
	КонецВыделения = СтрНайти(СтрокаПослеСсылки, "</a>");
	ТекстСсылки = Лев(СтрокаПослеСсылки, КонецВыделения - 1);
	Результат.Вставить("Представление", ТекстСсылки);
	Результат.Вставить("Ссылка", Ссылка);
	
	Возврат Результат;
	
КонецФункции

// Обработчик события СвойстваПередУдалениемСсылочногоОбъекта.
// Выполняет поиск ссылок на удаляемые объекты в таблице зависимостей дополнительных реквизитов.
//
Процедура ПередУдалениемСсылочногоОбъекта(Объект, Отказ) Экспорт
	Если Объект.ОбменДанными.Загрузка = Истина
		Или Отказ Тогда
		Возврат;
	КонецЕсли;
	
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		// В неразделенном режиме не проверяем.
		Возврат;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	Зависимости.Ссылка КАК Ссылка
		|ИЗ
		|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.ЗависимостиДополнительныхРеквизитов КАК Зависимости
		|ГДЕ
		|	Зависимости.Значение = &Значение
		|
		|УПОРЯДОЧИТЬ ПО
		|	Ссылка";
	Запрос.УстановитьПараметр("Значение", Объект.Ссылка);
	Результат = Запрос.Выполнить().Выгрузить();
	
	Для Каждого Строка Из Результат Цикл
		Блокировка = Новый БлокировкаДанных;
		ЭлементБлокировки = Блокировка.Добавить("ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения");
		ЭлементБлокировки.УстановитьЗначение("Ссылка", Строка.Ссылка);
		Блокировка.Заблокировать();
		
		РеквизитОбъект = Строка.Ссылка.ПолучитьОбъект();// ПланВидовХарактеристикОбъект.ДополнительныеРеквизитыИСведения
		ПараметрыОтбора = Новый Структура("Значение", Объект.Ссылка);
		НайденныеСтроки = РеквизитОбъект.ЗависимостиДополнительныхРеквизитов.НайтиСтроки(ПараметрыОтбора);
		Для Каждого Зависимость Из НайденныеСтроки Цикл
			РеквизитОбъект.ЗависимостиДополнительныхРеквизитов.Удалить(Зависимость);
		КонецЦикла;
		РеквизитОбъект.Записать();
	КонецЦикла;
КонецПроцедуры

// Проверяет наличие объектов, использующих свойство.
//
// Параметры:
//  Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения.
//
// Возвращаемое значение:
//  Булево -  Истина, если найден хотя бы один объект.
//
Функция ДополнительноеСвойствоИспользуется(Свойство) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Свойство", Свойство);
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	ИСТИНА КАК ЗначениеИстина
	|ИЗ
	|	РегистрСведений.ДополнительныеСведения КАК ДополнительныеСведения
	|ГДЕ
	|	ДополнительныеСведения.Свойство = &Свойство";
	
	Если НЕ Запрос.Выполнить().Пустой() Тогда
		Возврат Истина;
	КонецЕсли;
	
	ВидыОбъектовМетаданных = Новый Массив;
	ВидыОбъектовМетаданных.Добавить("ПланыОбмена");
	ВидыОбъектовМетаданных.Добавить("Справочники");
	ВидыОбъектовМетаданных.Добавить("Документы");
	ВидыОбъектовМетаданных.Добавить("ПланыВидовХарактеристик");
	ВидыОбъектовМетаданных.Добавить("ПланыСчетов");
	ВидыОбъектовМетаданных.Добавить("ПланыВидовРасчета");
	ВидыОбъектовМетаданных.Добавить("БизнесПроцессы");
	ВидыОбъектовМетаданных.Добавить("Задачи");
	
	ТаблицыОбъектов = Новый Массив;
	Для каждого ВидОбъектовМетаданных Из ВидыОбъектовМетаданных Цикл
		Для каждого ОбъектМетаданных Из Метаданные[ВидОбъектовМетаданных] Цикл
			
			Если ЭтоОбъектМетаданныхСоСвойствами(ОбъектМетаданных, "ДополнительныеРеквизиты") Тогда
				ТаблицыОбъектов.Добавить(ОбъектМетаданных.ПолноеИмя());
			КонецЕсли;
			
		КонецЦикла;
	КонецЦикла;
	
	ТекстЗапроса =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	ИСТИНА КАК ЗначениеИстина
	|ИЗ
	|	ИмяТаблицы КАК ТекущаяТаблица
	|ГДЕ
	|	ТекущаяТаблица.Свойство = &Свойство";
	
	Для каждого Таблица Из ТаблицыОбъектов Цикл
		Запрос.Текст = СтрЗаменить(ТекстЗапроса, "ИмяТаблицы", Таблица + ".ДополнительныеРеквизиты");
		Если НЕ Запрос.Выполнить().Пустой() Тогда // @skip-check query-in-loop - запрос к разным таблицам.
			Возврат Истина;
		КонецЕсли;
	КонецЦикла;
	
	Возврат Ложь;
	
КонецФункции

// Проверяет использует ли объект метаданных свойства определенного вида (кроме доп. сведений).
// Проверка предназначена для контроля ссылочной целостности, поэтому
// проверка встраивания пропускается.
//
Функция ЭтоОбъектМетаданныхСоСвойствами(ОбъектМетаданных, ВидСвойств) Экспорт
	
	Если ОбъектМетаданных = Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ТабличнаяЧасть = ОбъектМетаданных.ТабличныеЧасти.Найти(ВидСвойств);
	Если ТабличнаяЧасть = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Реквизит = ТабличнаяЧасть.Реквизиты.Найти("Свойство");
	Если Реквизит = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если НЕ Реквизит.Тип.СодержитТип(Тип("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения")) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Реквизит = ТабличнаяЧасть.Реквизиты.Найти("Значение");
	Если Реквизит = Неопределено Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

// Возвращает наименование предопределенного набора полученное
// из объекта метаданных, найденного через имя предопределенного набора.
// 
// Параметры:
//  Набор - СправочникСсылка.НаборыДополнительныхРеквизитовИСведений,
//        - Строка - полное имя предопределенного элемента.
//
Функция НаименованиеПредопределенногоНабора(Набор) Экспорт
	
	Если ТипЗнч(Набор) = Тип("Строка") Тогда
		ИмяПредопределенного = Набор;
	Иначе
		ИмяПредопределенного = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Набор, "ИмяПредопределенныхДанных");
	КонецЕсли;
	
	Позиция = СтрНайти(ИмяПредопределенного, "_");
	ПерваяЧастьИмени =  Лев(ИмяПредопределенного, Позиция - 1);
	ВтораяЧастьИмени = Прав(ИмяПредопределенного, СтрДлина(ИмяПредопределенного) - Позиция);
	
	ПолноеИмя = ПерваяЧастьИмени + "." + ВтораяЧастьИмени;
	
	ОбъектМетаданных = ОбщегоНазначения.ОбъектМетаданныхПоПолномуИмени(ПолноеИмя);
	Если ОбъектМетаданных = Неопределено Тогда
		Если ТипЗнч(Набор) = Тип("Строка") Тогда
			Возврат "";
		Иначе
			Возврат Строка(Набор);
		КонецЕсли;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ОбъектМетаданных.ПредставлениеСписка) Тогда
		Наименование = ОбъектМетаданных.ПредставлениеСписка;
		
	ИначеЕсли ЗначениеЗаполнено(ОбъектМетаданных.Синоним) Тогда
		Наименование = ОбъектМетаданных.Синоним;
	Иначе
		Если ТипЗнч(Набор) = Тип("Строка") Тогда
			Наименование = "";
		Иначе
			Наименование = Строка(Набор);
		КонецЕсли;
	КонецЕсли;
	
	Возврат Наименование;
	
КонецФункции

// Обновление состава верхней группы для использования при настройке
// состава полей динамического списка и его настройки (отборы, ...).
//
// Параметры:
//  Группа - СправочникСсылка.НаборыДополнительныхРеквизитовИСведений - элемент с признаком ЭтоГруппа = Истина.
//
Процедура ПроверитьОбновитьСоставСвойствГруппы(Группа) Экспорт
	
	УстановитьПривилегированныйРежим(Истина);
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Группа", Группа);
	Запрос.Текст =
	"ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ДополнительныеРеквизиты.Свойство КАК Свойство,
	|	ДополнительныеРеквизиты.ИмяПредопределенногоНабора КАК ИмяПредопределенногоНабора
	|ИЗ
	|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК ДополнительныеРеквизиты
	|ГДЕ
	|	ДополнительныеРеквизиты.Ссылка.Родитель = &Группа
	|
	|УПОРЯДОЧИТЬ ПО
	|	Свойство
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ДополнительныеСведения.Свойство КАК Свойство,
	|	ДополнительныеСведения.ИмяПредопределенногоНабора КАК ИмяПредопределенногоНабора
	|ИЗ
	|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения КАК ДополнительныеСведения
	|ГДЕ
	|	ДополнительныеСведения.Ссылка.Родитель = &Группа
	|
	|УПОРЯДОЧИТЬ ПО
	|	Свойство";
	
	РезультатЗапроса = Запрос.ВыполнитьПакет();
	ДополнительныеРеквизитыГруппы = РезультатЗапроса[0].Выгрузить();
	ДополнительныеСведенияГруппы  = РезультатЗапроса[1].Выгрузить();
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
	ЭлементБлокировки.УстановитьЗначение("Ссылка", Группа);
	Блокировка.Заблокировать();
	
	ГруппаОбъект = Группа.ПолучитьОбъект();
	
	Обновить = Ложь;
	
	Если ГруппаОбъект.ДополнительныеРеквизиты.Количество() <> ДополнительныеРеквизитыГруппы.Количество() Тогда
		Обновить = Истина;
	КонецЕсли;
	
	Если ГруппаОбъект.ДополнительныеСведения.Количество() <> ДополнительныеСведенияГруппы.Количество() Тогда
		Обновить = Истина;
	КонецЕсли;
	
	Если Не Обновить Тогда
		Индекс = 0;
		Для каждого Строка Из ГруппаОбъект.ДополнительныеРеквизиты Цикл
			Если Строка.Свойство <> ДополнительныеРеквизитыГруппы[Индекс].Свойство Тогда
				Обновить = Истина;
			КонецЕсли;
			Индекс = Индекс + 1;
		КонецЦикла;
	КонецЕсли;
	
	Если Не Обновить Тогда
		Индекс = 0;
		Для каждого Строка Из ГруппаОбъект.ДополнительныеСведения Цикл
			Если Строка.Свойство <> ДополнительныеСведенияГруппы[Индекс].Свойство Тогда
				Обновить = Истина;
			КонецЕсли;
			Индекс = Индекс + 1;
		КонецЦикла;
	КонецЕсли;
	
	Если Не Обновить Тогда
		Возврат;
	КонецЕсли;
	
	ГруппаОбъект.ДополнительныеРеквизиты.Загрузить(ДополнительныеРеквизитыГруппы);
	ГруппаОбъект.ДополнительныеСведения.Загрузить(ДополнительныеСведенияГруппы);
	ГруппаОбъект.Записать();
	
КонецПроцедуры

// Возвращает перечисляемые значения указанного свойства.
//
// Параметры:
//  Свойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения - свойство для
//             которого нужно получить перечисляемые значения.
//           - Массив
// 
// Возвращаемое значение:
//  Массив из СправочникСсылка - значения свойства, если есть.
//
Функция ДополнительныеЗначенияСвойства(Свойство) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Параметры.Вставить("Свойство", Свойство);
	Запрос.Текст =
		"ВЫБРАТЬ
		|	ЗначенияСвойствОбъектовИерархия.Ссылка КАК Ссылка,
		|	ЗначенияСвойствОбъектовИерархия.Владелец КАК Свойство
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектовИерархия КАК ЗначенияСвойствОбъектовИерархия
		|ГДЕ
		|	ЗначенияСвойствОбъектовИерархия.Владелец В (&Свойство)
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ
		|	ЗначенияСвойствОбъектов.Ссылка КАК Ссылка,
		|	ЗначенияСвойствОбъектов.Владелец КАК Свойство
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
		|ГДЕ
		|	ЗначенияСвойствОбъектов.Владелец В (&Свойство)";
	
	Если ТипЗнч(Свойство) = Тип("ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения") Тогда
		Результат = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ссылка");
	Иначе
		Результат = Запрос.Выполнить().Выгрузить();
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

Процедура СоздатьПредопределенныеНаборыСвойств() Экспорт
	
	ПредопределенныеНаборыСвойств = УправлениеСвойствамиПовтИсп.ПредопределенныеНаборыСвойств();
	НаименованияНаборовСвойств    = УправлениеСвойствамиПовтИсп.НаименованияНаборовСвойств();
	
	ВременнаяТаблица = Новый ТаблицаЗначений;
	ВременнаяТаблица.Колонки.Добавить("Имя",          Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(150)));
	ВременнаяТаблица.Колонки.Добавить("Используется", Новый ОписаниеТипов("Булево"));
	ВременнаяТаблица.Колонки.Добавить("ЭтоДочерний",  Новый ОписаниеТипов("Булево"));
	ВременнаяТаблица.Колонки.Добавить("Наименование", Новый ОписаниеТипов("Строка",,,, Новый КвалификаторыСтроки(100)));
	ВременнаяТаблица.Колонки.Добавить("ЭтоГруппа",    Новый ОписаниеТипов("Булево"));
	ВременнаяТаблица.Колонки.Добавить("Ссылка",       Новый ОписаниеТипов("СправочникСсылка.НаборыДополнительныхРеквизитовИСведений"));
	Для Каждого ПредопределенныйНабор Из ПредопределенныеНаборыСвойств Цикл
		Если ТипЗнч(ПредопределенныйНабор.Ключ) = Тип("Строка") Тогда
			Продолжить;
		КонецЕсли;
		
		Строка = ВременнаяТаблица.Добавить();
		ЗаполнитьЗначенияСвойств(Строка, ПредопределенныйНабор.Значение);
		Если ЗначениеЗаполнено(ПредопределенныйНабор.Значение.Родитель) Тогда
			// Если изменился дочерний набор - все равно выбираем для обработки набор верхнего уровня.
			Строка.Ссылка      = ПредопределенныйНабор.Значение.Родитель;
			Строка.ЭтоДочерний = Истина;
		КонецЕсли;
		
		Если ПредопределенныйНабор.Значение.Используется = Неопределено Тогда
			Строка.Используется = Истина;
		КонецЕсли;
	КонецЦикла;
	
	НесколькоЯзыков = Ложь;
	Для Каждого Язык Из Метаданные.Языки Цикл
		Если Язык.КодЯзыка <> ТекущийЯзык().КодЯзыка Тогда
			НесколькоЯзыков = Истина;
			Прервать;
		КонецЕсли
	КонецЦикла;
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ОписаниеНаборов", ВременнаяТаблица);
	Запрос.УстановитьПараметр("НесколькоЯзыков", НесколькоЯзыков);
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ОписаниеНаборов.Ссылка КАК Ссылка,
	|	ОписаниеНаборов.Имя КАК Имя,
	|	ОписаниеНаборов.Наименование КАК Наименование,
	|	ОписаниеНаборов.ЭтоГруппа КАК ЭтоГруппа,
	|	ОписаниеНаборов.ЭтоДочерний КАК ЭтоДочерний,
	|	ОписаниеНаборов.Используется КАК Используется
	|ПОМЕСТИТЬ ОписаниеНаборов
	|ИЗ
	|	&ОписаниеНаборов КАК ОписаниеНаборов
	|;
	|
	|////////////////////////////////////////////////////////////////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ОписаниеНаборов.Ссылка КАК Ссылка
	|ИЗ
	|	ОписаниеНаборов КАК ОписаниеНаборов
	|ГДЕ
	|	НЕ ИСТИНА В
	|				(ВЫБРАТЬ ПЕРВЫЕ 1
	|					ИСТИНА
	|				ИЗ
	|					Справочник.НаборыДополнительныхРеквизитовИСведений КАК Наборы
	|				ГДЕ
	|					ОписаниеНаборов.Имя = Наборы.ИмяПредопределенногоНабора
	|					И ОписаниеНаборов.Используется = Наборы.Используется
	|					И ОписаниеНаборов.Наименование = Наборы.Наименование
	|					И НЕ Наборы.ПометкаУдаления
	|					И &НесколькоЯзыков = ЛОЖЬ)
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОписаниеНаборов.Ссылка
	|ИЗ
	|	ОписаниеНаборов КАК ОписаниеНаборов
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК ДополнительныеРеквизиты
	|		ПО ОписаниеНаборов.Ссылка = ДополнительныеРеквизиты.Ссылка
	|ГДЕ
	|	ДополнительныеРеквизиты.ИмяПредопределенногоНабора <> ОписаниеНаборов.Имя
	|	И НЕ ОписаниеНаборов.ЭтоДочерний
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	ОписаниеНаборов.Ссылка
	|ИЗ
	|	ОписаниеНаборов КАК ОписаниеНаборов
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения КАК ДополнительныеСведения
	|		ПО ОписаниеНаборов.Ссылка = ДополнительныеСведения.Ссылка
	|ГДЕ
	|	ДополнительныеСведения.ИмяПредопределенногоНабора <> ОписаниеНаборов.Имя
	|	И НЕ ОписаниеНаборов.ЭтоДочерний";
	ОбрабатываемыеНаборы = Запрос.Выполнить().Выгрузить();
	
	Для Каждого Строка Из ОбрабатываемыеНаборы Цикл
		СвойстваНабора = ПредопределенныеНаборыСвойств.Получить(Строка.Ссылка); // см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
		Объект         = СвойстваНабора.Ссылка.ПолучитьОбъект();
		СоздатьНаборСвойств(Объект, СвойстваНабора);
		
		Для Каждого ДочернийНабор Из СвойстваНабора.ДочерниеНаборы Цикл
			СвойстваНабора = ДочернийНабор.Значение; // см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
			ДочернийОбъект = СвойстваНабора.Ссылка.ПолучитьОбъект();
			СоздатьНаборСвойств(ДочернийОбъект, СвойстваНабора, НаименованияНаборовСвойств, Объект.Ссылка);
		КонецЦикла;
	КонецЦикла;
	
КонецПроцедуры

// Параметры:
//  СвойстваНабора см. Справочники.НаборыДополнительныхРеквизитовИСведений.СвойстваНабора
//
Процедура СоздатьНаборСвойств(Объект, СвойстваНабора, НаименованияНаборовСвойств = Неопределено, Родитель = Неопределено)
	
	Записать = Ложь;
	Если Объект = Неопределено Тогда
		Если СвойстваНабора.ЭтоГруппа
			Или (СвойстваНабора.ДочерниеНаборы <> Неопределено
				И СвойстваНабора.ДочерниеНаборы.Количество() <> 0) Тогда
			Объект = Справочники.НаборыДополнительныхРеквизитовИСведений.СоздатьГруппу();
		Иначе
			Объект = Справочники.НаборыДополнительныхРеквизитовИСведений.СоздатьЭлемент();
		КонецЕсли;
		Если Родитель <> Неопределено Тогда
			Объект.Родитель = Родитель;
		КонецЕсли;
		Объект.УстановитьСсылкуНового(СвойстваНабора.Ссылка);
		Объект.ИмяПредопределенногоНабора = СвойстваНабора.Имя;
		Записать = Истина;
	КонецЕсли;
	
	Если СвойстваНабора.Используется <> Неопределено Тогда
		Если Объект.Используется <> СвойстваНабора.Используется Тогда
			Объект.Используется = СвойстваНабора.Используется;
			Записать = Истина;
		КонецЕсли;
	Иначе
		Если Объект.Используется <> Истина Тогда
			Объект.Используется = Истина;
			Записать = Истина;
		КонецЕсли;
	КонецЕсли;
	
	Если Объект.Наименование <> СвойстваНабора.Наименование Тогда
		Объект.Наименование = СвойстваНабора.Наименование;
		Записать = Истина;
	КонецЕсли;
	
	Если Объект.ИмяПредопределенногоНабора <> СвойстваНабора.Имя Тогда
		Объект.ИмяПредопределенногоНабора = СвойстваНабора.Имя;
		Записать = Истина;
	КонецЕсли;
	
	Если Родитель = Неопределено Тогда
		Для Каждого СтрокаТаблицы Из Объект.ДополнительныеРеквизиты Цикл
			Если СтрокаТаблицы.ИмяПредопределенногоНабора <> СвойстваНабора.Имя Тогда
				СтрокаТаблицы.ИмяПредопределенногоНабора = СвойстваНабора.Имя;
				Записать = Истина;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если Родитель = Неопределено Тогда
		Для Каждого СтрокаТаблицы Из Объект.ДополнительныеСведения Цикл
			Если СтрокаТаблицы.ИмяПредопределенногоНабора <> СвойстваНабора.Имя Тогда
				СтрокаТаблицы.ИмяПредопределенногоНабора = СвойстваНабора.Имя;
				Записать = Истина;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	Если Объект.ПометкаУдаления Тогда
		Объект.ПометкаУдаления = Ложь;
		Записать = Истина;
	КонецЕсли;
	
	Если НаименованияНаборовСвойств <> Неопределено Тогда
		
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
			МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер");
			
			Для Каждого Язык Из Метаданные.Языки Цикл
				Если Язык.КодЯзыка = ТекущийЯзык().КодЯзыка Тогда
					Продолжить;
				КонецЕсли;
				
				ЛокализованныеНаименования = НаименованияНаборовСвойств[Язык.КодЯзыка];
				ЛокализованноеНаименование = ЛокализованныеНаименования[СвойстваНабора.Имя];
				СуффиксЯзыка = МодульМультиязычностьСервер.СуффиксЯзыка(Язык.КодЯзыка);
				Если ЗначениеЗаполнено(СуффиксЯзыка) 
					И ЗначениеЗаполнено(ЛокализованноеНаименование)
					И ПустаяСтрока(Объект["Наименование" + СуффиксЯзыка])
					И ЛокализованноеНаименование <> Объект["Наименование" + СуффиксЯзыка] Тогда
						Объект["Наименование" + СуффиксЯзыка] = ЛокализованноеНаименование;
						Записать = Истина;
				КонецЕсли;

				
			КонецЦикла;
		КонецЕсли;
		
	КонецЕсли;
	
	Если Записать Тогда
		ОбновлениеИнформационнойБазы.ЗаписатьОбъект(Объект, Ложь);
	КонецЕсли;
	
КонецПроцедуры

Функция НаименованияНаборовСвойств() Экспорт
	
	ПредопределенныеДанные = ПредопределенныеНаборыСвойств();
	
	Результат = Новый Соответствие;
	Для Каждого Язык Из Метаданные.Языки Цикл
		Наименования = Новый Соответствие;
		УправлениеСвойствамиПереопределяемый.ПриПолученииНаименованийНаборовСвойств(Наименования, Язык.КодЯзыка);
		
		ИмяКолонки = "Наименование" + "_" + Язык.КодЯзыка;
		Если ПредопределенныеДанные.Колонки.Найти(ИмяКолонки) <> Неопределено Тогда
			Для Каждого ДанныеЭлемента Из ПредопределенныеДанные Цикл
				Наименования.Вставить(ДанныеЭлемента.ИмяПредопределенногоНабора, ДанныеЭлемента[ИмяКолонки]);
			КонецЦикла;
		КонецЕсли;
		Результат[Язык.КодЯзыка] = Наименования;
	КонецЦикла;
	
	Возврат Новый ФиксированноеСоответствие(Результат);
КонецФункции

Функция ПредопределенныеНаборыСвойств() Экспорт
	
	ЛокализуемыеРеквизитыОбъекта = Новый Соответствие();
	ЛокализуемыеРеквизитыОбъекта.Вставить("Наименование", Истина);
	
	ПредопределенныеДанные = ОбновлениеИнформационнойБазыСлужебный.ПредопределенныеДанныеОбъекта(Метаданные.Справочники.НаборыДополнительныхРеквизитовИСведений,
	Справочники.НаборыДополнительныхРеквизитовИСведений, ЛокализуемыеРеквизитыОбъекта);
	Возврат ПредопределенныеДанные;

КонецФункции

Процедура УдалитьНедопустимыеСимволы(Строка) Экспорт
	НедопустимыеСимволы = """'`/\[]{}:;|-=?*<>,.()+#№@!%^&~«»";
	Строка = СтрСоединить(СтрРазделить(Строка, НедопустимыеСимволы, Истина));
КонецПроцедуры

Процедура ОчиститьНеиспользуемыеНастройки() Экспорт
	
	Отбор = Новый Структура;
	Отбор.Вставить("КлючНастроек", "КлючНазначенияИспользованияФормы");
	УдалитьНастройкуИзХранилища(Отбор);
	
	Отбор.КлючНастроек = "КлючСохраненияПоложенияОкнаФормы";
	УдалитьНастройкуИзХранилища(Отбор);
	
КонецПроцедуры

Процедура УдалитьНастройкуИзХранилища(Отбор)
	
	ВыборкаНастроек = ХранилищеСистемныхНастроек.Выбрать(Отбор);
	Пока СледующаяНастройка(ВыборкаНастроек) Цикл
		Попытка
			КлючОбъекта = ВыборкаНастроек.КлючОбъекта;
			Если СтрНачинаетсяС(КлючОбъекта, "КлючНаборовСвойств") Тогда
				ОбщегоНазначения.ХранилищеСистемныхНастроекУдалить(ВыборкаНастроек.КлючОбъекта,
					ВыборкаНастроек.КлючНастроек,
					ВыборкаНастроек.Пользователь);
			КонецЕсли;
		Исключение
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			ТекстОшибки = НСтр("ru = 'При очистке настроек в обработчике %1
				|возникла ошибка:
				|%2'");
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки,
				"УправлениеСвойствамиСлужебный.ОчиститьНеиспользуемыеНастройки",
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
			ЗаписьЖурналаРегистрации(
				ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(),
				УровеньЖурналаРегистрации.Предупреждение,,,
				ТекстОшибки);
		КонецПопытки;
	КонецЦикла;
	
КонецПроцедуры

Функция СледующаяНастройка(Выборка)
	
	ЕстьСледующий = Ложь;
	Попытка
		ЕстьСледующий = Выборка.Следующий();
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ТекстОшибки = НСтр("ru = 'При чтении настроек в обработчике %1
			|возникла ошибка:
			|%2'");
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстОшибки,
			"УправлениеСвойствамиСлужебный.ОчиститьНеиспользуемыеНастройки",
			ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
		ЗаписьЖурналаРегистрации(
			ОбновлениеИнформационнойБазы.СобытиеЖурналаРегистрации(),
			УровеньЖурналаРегистрации.Предупреждение,,,
			ТекстОшибки);
	КонецПопытки;
	
	Возврат ЕстьСледующий;
	
КонецФункции

Функция НаименованиеУжеИспользуется(Свойство, НаборСвойств, Наименование) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 1
		|	СвойстваНабора.Свойство КАК Свойство,
		|	РеквизитыИСведения.ЭтоДополнительноеСведение КАК ЭтоДополнительноеСведение
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СвойстваНабора
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК РеквизитыИСведения
		|		ПО (РеквизитыИСведения.Ссылка = СвойстваНабора.Свойство)
		|ГДЕ
		|	РеквизитыИСведения.Заголовок = &Наименование
		|	И СвойстваНабора.Ссылка = &НаборСвойств
		|	И СвойстваНабора.Свойство <> &Ссылка
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	СвойстваНабора.Свойство КАК Свойство,
		|	РеквизитыИСведения.ЭтоДополнительноеСведение КАК ЭтоДополнительноеСведение
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения КАК СвойстваНабора
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК РеквизитыИСведения
		|		ПО (РеквизитыИСведения.Ссылка = СвойстваНабора.Свойство)
		|ГДЕ
		|	РеквизитыИСведения.Заголовок = &Наименование
		|	И СвойстваНабора.Ссылка = &НаборСвойств
		|	И СвойстваНабора.Свойство <> &Ссылка";
	
	Запрос.УстановитьПараметр("Ссылка",       Свойство);
	Запрос.УстановитьПараметр("НаборСвойств", НаборСвойств);
	Запрос.УстановитьПараметр("Наименование", Наименование);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Если НЕ Выборка.Следующий() Тогда
		Возврат "";
	КонецЕсли;
	
	Если Выборка.ЭтоДополнительноеСведение Тогда
		ТекстВопроса = НСтр("ru = 'Существует дополнительное сведение с наименованием
		                          |""%1"".'");
	Иначе
		ТекстВопроса = НСтр("ru = 'Существует дополнительный реквизит с наименованием
		                          |""%1"".'");
	КонецЕсли;
	
	ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		ТекстВопроса + Символы.ПС + Символы.ПС
		                         + НСтр("ru = 'Рекомендуется использовать другое наименование,
		                         |иначе программа может работать некорректно.'"),
		Наименование);
	
	Возврат ТекстВопроса;
	
КонецФункции

Функция ИмяУжеИспользуется(Знач Имя, Знач ТекущееСвойство) Экспорт
	
	НовоеИмя = Имя;
	УдалитьНедопустимыеСимволы(НовоеИмя);
	Если НовоеИмя <> Имя
		Или ИмяНачинаетсяСЦифры(Имя)
		Или СтрРазделить(НовоеИмя, " ", Истина).Количество() > 1 Тогда
		
		ТекстВопроса = НСтр("ru = 'Имя (группа Для разработчиков) должно состоять из одного слова, начинаться с буквы и не содержать специальных символов, кроме ""_"".'");
		Возврат ТекстВопроса;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	Свойства.ЭтоДополнительноеСведение
	|ИЗ
	|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
	|ГДЕ
	|	Свойства.Имя = &Имя
	|	И Свойства.Ссылка <> &Ссылка";
	
	Запрос.УстановитьПараметр("Ссылка", ТекущееСвойство);
	Запрос.УстановитьПараметр("Имя",    Имя);
	
	Выборка = Запрос.Выполнить().Выбрать();
	
	Если НЕ Выборка.Следующий() Тогда
		Возврат "";
	КонецЕсли;
	
	Если Выборка.ЭтоДополнительноеСведение Тогда
		ТекстВопроса = НСтр("ru = 'Существует дополнительное сведение с именем
		                          |""%1"".'");
	Иначе
		ТекстВопроса = НСтр("ru = 'Существует дополнительный реквизит с именем
		                          |""%1"".'");
	КонецЕсли;
	
	ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		ТекстВопроса + Символы.ПС + Символы.ПС
		                         + НСтр("ru = 'Рекомендуется использовать другое имя,
		                         |иначе программа может работать некорректно.
		                         |
		                         |Создать новое имя и продолжить запись?'"),
		Имя);
	
	Возврат ТекстВопроса;
	
КонецФункции

Функция ИмяНачинаетсяСЦифры(ИмяРеквизита) Экспорт
	ПервыйСимвол = Лев(ИмяРеквизита, 1);
	Если СтрНайти("0123456789", ПервыйСимвол) > 0 Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
КонецФункции

Функция ИдентификаторДляФормулУжеИспользуется(Знач ИдентификаторДляФормул, Знач ТекущееСвойство) Экспорт
	
	ПроверочныйИдентификатор = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.ИдентификаторДляФормул(ИдентификаторДляФормул);
	Если ВРег(ИдентификаторДляФормул) <> ВРег(ПроверочныйИдентификатор) Тогда
		ТекстВопроса = НСтр("ru = 'Идентификатор ""%1"" не соответствует правилам именования переменных.
		                          |Идентификатор не должен содержать пробелов и специальных символов.'");
		ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			ТекстВопроса,
			ИдентификаторДляФормул);
		Возврат ТекстВопроса;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	Свойства.ЭтоДополнительноеСведение
	|ИЗ
	|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
	|ГДЕ
	|	Свойства.ИдентификаторДляФормул = &ИдентификаторДляФормул
	|	И Свойства.Ссылка <> &Ссылка";
	
	Запрос.УстановитьПараметр("Ссылка", ТекущееСвойство);
	Запрос.УстановитьПараметр("ИдентификаторДляФормул", ИдентификаторДляФормул);
	
	НачатьТранзакцию();
	Попытка
		Выборка = Запрос.Выполнить().Выбрать();
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	Если НЕ Выборка.Следующий() Тогда
		Возврат "";
	КонецЕсли;
	
	Если Выборка.ЭтоДополнительноеСведение Тогда
		ТекстВопроса = НСтр("ru = 'Существует дополнительное сведение с идентификатором для формул
		                          |""%1"".'");
	Иначе
		ТекстВопроса = НСтр("ru = 'Существует дополнительный реквизит с идентификатором для формул
		                          |""%1"".'");
	КонецЕсли;
	
	ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		ТекстВопроса + Символы.ПС + Символы.ПС
		                         + НСтр("ru = 'Рекомендуется использовать другой идентификатор для формул,
		                         |иначе программа может работать некорректно.'"),
		ИдентификаторДляФормул);
	
	Возврат ТекстВопроса;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// Вспомогательные процедуры и функции.

// Возвращает основной набор свойств владельца.
//
// Параметры:
//  ВладелецСвойств - ссылка или Объект владельца свойств.
//
// Возвращаемое значение:
//  СправочникСсылка.НаборыДополнительныхРеквизитовИСведений
//  
Функция ПолучитьОсновнойНаборСвойствДляОбъекта(ВладелецСвойств)
	
	Если ОбщегоНазначения.ЗначениеСсылочногоТипа(ВладелецСвойств) Тогда
		Ссылка = ВладелецСвойств;
	Иначе
		Ссылка = ВладелецСвойств.Ссылка;
	КонецЕсли;
	
	МетаданныеОбъекта = Ссылка.Метаданные();
	ИмяОбъектаМетаданных = МетаданныеОбъекта.Имя;
	
	ВидОбъектаМетаданных = ОбщегоНазначения.ВидОбъектаПоСсылке(Ссылка);
	
	ИмяЭлемента = ВидОбъектаМетаданных + "_" + ИмяОбъектаМетаданных;
	ОсновнойНабор = УправлениеСвойствами.НаборСвойствПоИмени(ИмяЭлемента);
	Если ОсновнойНабор = Неопределено Тогда
		ОсновнойНабор = Справочники.НаборыДополнительныхРеквизитовИСведений[ИмяЭлемента];
	КонецЕсли;
	
	Возврат ОсновнойНабор;
	
КонецФункции

// Используется при обновлении информационной базы.
Функция ЕстьИзмененияПредставленийОбъектовМетаданныхСоСвойствами()
	
	УстановитьПривилегированныйРежим(Истина);
	
	Справочники.НаборыДополнительныхРеквизитовИСведений.ОбновитьСоставНаименованийПредопределенныхНаборов();
	
	ПоследниеИзменения = СтандартныеПодсистемыСервер.ИзмененияПараметраРаботыПрограммы(
		"СтандартныеПодсистемы.Свойства.ПредопределенныеНаборыДополнительныхРеквизитовИСведений");
	
	Если ПоследниеИзменения = Неопределено
	 Или ПоследниеИзменения.Количество() > 0 Тогда
		
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

Функция НеобходимоПеренестиЗначениеИзСсылки(Значение, Представление)
	
	Если ЗначениеЗаполнено(Представление) И Лев(Значение, 7) = "<a href" Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

Функция ЗначениеБезСсылки(Значение, Представление)
	
	Если Не ЗначениеЗаполнено(Представление) Или Лев(Значение, 7) <> "<a href" Тогда
		Возврат Значение;
	КонецЕсли;
	
	НачалоСсылки = "<a href = """;
	КонецСсылки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(""">%1</a>", Представление);
	
	Результат = СтрЗаменить(Значение, НачалоСсылки, "");
	Результат = СтрЗаменить(Результат, КонецСсылки, "");
	Возврат Результат;
	
КонецФункции

// Используется в форме списка справочника НаборыДополнительныхРеквизитовИСведений
// и плана видов характеристик ДополнительныеРеквизитыИСведения.
//
Процедура ОбновитьСписокСвойствТекущегоНабора(Форма, Набор, ВидСвойств, ТекущаяДоступность = Неопределено) Экспорт
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Набор", Набор);
	Запрос.УстановитьПараметр("ЭтоОсновнойЯзык", ОбщегоНазначения.ЭтоОсновнойЯзык());
	Запрос.УстановитьПараметр("КодЯзыка", ТекущийЯзык().КодЯзыка);
	Запрос.УстановитьПараметр("ВидСвойств", ВидСвойств);
	
	Если Не Форма.ПоказатьНеиспользуемыеРеквизиты Тогда
		Запрос.Текст =
		"ВЫБРАТЬ
		|	СвойстваНаборов.НомерСтроки,
		|	СвойстваНаборов.Свойство,
		|	СвойстваНаборов.ПометкаУдаления,
		|	Свойства.Заголовок КАК Заголовок,
		|	Свойства.ВладелецДополнительныхЗначений,
		|	Свойства.ЗаполнятьОбязательно,
		|	Свойства.ТипЗначения КАК ТипЗначения,
		|	ИСТИНА КАК Общее,
		|	ВЫБОР
		|		КОГДА Свойства.ПометкаУдаления = ИСТИНА
		|			ТОГДА 12
		|		КОГДА Свойства.ВидСвойств = ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Метки)
		|			ТОГДА Свойства.ЦветСвойств.Порядок + 1
		|		ИНАЧЕ 11
		|	КОНЕЦ КАК НомерКартинки,
		|	Свойства.Подсказка КАК Подсказка,
		|	Свойства.ЗаголовокФормыЗначения КАК ЗаголовокФормыЗначения,
		|	Свойства.ЗаголовокФормыВыбораЗначения КАК ЗаголовокФормыВыбораЗначения
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СвойстваНаборов
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
		|		ПО СвойстваНаборов.Свойство = Свойства.Ссылка
		|ГДЕ
		|	СвойстваНаборов.Свойство.ЭтоДополнительноеСведение = &ЭтоНаборыДополнительныхСведений
		|	И СвойстваНаборов.Свойство.ВидСвойств В (ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.ПустаяСсылка), &ВидСвойств)
		|	И СвойстваНаборов.Ссылка = &Набор
		|
		|УПОРЯДОЧИТЬ ПО
		|	СвойстваНаборов.НомерСтроки
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	Наборы.ВерсияДанных КАК ВерсияДанных
		|ИЗ
		|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК Наборы
		|ГДЕ
		|	Наборы.Ссылка = &Набор";
	Иначе
		Запрос.Текст =
		"ВЫБРАТЬ
		|	Свойства.Ссылка КАК Свойство,
		|	Свойства.ПометкаУдаления КАК ПометкаУдаления,
		|	Свойства.Заголовок КАК Заголовок,
		|	Свойства.ВладелецДополнительныхЗначений,
		|	Свойства.ТипЗначения КАК ТипЗначения,
		|	ИСТИНА КАК Общее,
		|	ВЫБОР
		|		КОГДА Свойства.ПометкаУдаления = ИСТИНА
		|			ТОГДА 12
		|		КОГДА Свойства.ВидСвойств = ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Метки)
		|			ТОГДА Свойства.ЦветСвойств.Порядок + 1
		|		ИНАЧЕ 11
		|	КОНЕЦ КАК НомерКартинки,
		|	Свойства.Подсказка КАК Подсказка,
		|	Свойства.ЗаголовокФормыЗначения КАК ЗаголовокФормыЗначения,
		|	Свойства.ЗаголовокФормыВыбораЗначения КАК ЗаголовокФормыВыбораЗначения
		|ИЗ
		|	ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения КАК Свойства
		|		ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Представления КАК СвойстваПредставления
		|		ПО Свойства.Ссылка = СвойстваПредставления.Ссылка
		|		И СвойстваПредставления.КодЯзыка = &КодЯзыка
		|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты КАК СоставНабора
		|		ПО Свойства.Ссылка = СоставНабора.Свойство
		|ГДЕ
		|	Свойства.ЭтоДополнительноеСведение = &ЭтоНаборыДополнительныхСведений
		|	И Свойства.ВидСвойств В (ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.ПустаяСсылка), &ВидСвойств)
		|	И СоставНабора.Свойство ЕСТЬ NULL
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	""ВерсияДанных"" КАК ВерсияДанных";
	КонецЕсли;
	
	Если ВидСвойств = Перечисления.ВидыСвойств.ДополнительныеСведения Тогда
		Запрос.Текст = СтрЗаменить(
			Запрос.Текст,
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеРеквизиты",
			"Справочник.НаборыДополнительныхРеквизитовИСведений.ДополнительныеСведения");
		ЭтоНаборыДополнительныхСведений = Истина;
	ИначеЕсли ВидСвойств = Перечисления.ВидыСвойств.Метки Тогда
		Запрос.Текст = СтрЗаменить(
			Запрос.Текст,
			"В (ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.ПустаяСсылка), &ВидСвойств)",
			"= ЗНАЧЕНИЕ(Перечисление.ВидыСвойств.Метки)");
		ЭтоНаборыДополнительныхСведений = Ложь;
	Иначе
		ЭтоНаборыДополнительныхСведений = Ложь;
	КонецЕсли;
	Запрос.УстановитьПараметр("ЭтоНаборыДополнительныхСведений", ЭтоНаборыДополнительныхСведений);
	
	СуффиксТекущегоЯзыка = ОбщегоНазначения.СуффиксЯзыкаТекущегоПользователя();
	Если СуффиксТекущегоЯзыка = Неопределено Тогда
		
		Если Не Форма.ПоказатьНеиспользуемыеРеквизиты Тогда
			Позиция = СтрНайти(Запрос.Текст, "ГДЕ");
			Запрос.Текст = Лев(Запрос.Текст, Позиция - 1 ) 
				+ " ЛЕВОЕ СОЕДИНЕНИЕ ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения.Представления КАК СвойстваПредставления
				 |		ПО Свойства.Ссылка = СвойстваПредставления.Ссылка
				 |			И СвойстваПредставления.КодЯзыка = &КодЯзыка" + Сред(Запрос.Текст, Позиция -1);
		КонецЕсли;
		
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "Свойства.Заголовок КАК Заголовок", 
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.Заголовок, Свойства.Заголовок) КАК СТРОКА(150)) КАК Заголовок");
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "Свойства.Подсказка КАК Подсказка", 
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.Подсказка, Свойства.Подсказка) КАК СТРОКА(150)) КАК Подсказка");
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "Свойства.ЗаголовокФормыЗначения КАК ЗаголовокФормыЗначения", 
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.ЗаголовокФормыЗначения, Свойства.ЗаголовокФормыЗначения) КАК СТРОКА(150)) КАК ЗаголовокФормыЗначения");
		Запрос.Текст = СтрЗаменить(Запрос.Текст, "Свойства.ЗаголовокФормыВыбораЗначения КАК ЗаголовокФормыВыбораЗначения", 
			"ВЫРАЗИТЬ(ЕСТЬNULL(СвойстваПредставления.ЗаголовокФормыВыбораЗначения, Свойства.ЗаголовокФормыВыбораЗначения) КАК СТРОКА(150)) КАК ЗаголовокФормыВыбораЗначения");
	Иначе
	
		Если ЗначениеЗаполнено(СуффиксТекущегоЯзыка) И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Мультиязычность") Тогда
			МодульМультиязычностьСервер = ОбщегоНазначения.ОбщийМодуль("МультиязычностьСервер");
			МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "Свойства.Заголовок КАК Заголовок");
			Если Форма.ПоказатьНеиспользуемыеРеквизиты Тогда
				МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "Свойства.Подсказка КАК Подсказка");
				МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "Свойства.ЗаголовокФормыЗначения КАК ЗаголовокФормыЗначения");
				МодульМультиязычностьСервер.ИзменитьПолеЗапросаПодТекущийЯзык(Запрос.Текст, "Свойства.ЗаголовокФормыВыбораЗначения КАК ЗаголовокФормыВыбораЗначения");
			КонецЕсли;
		КонецЕсли;
		
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		РезультатыЗапроса = Запрос.ВыполнитьПакет();
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
	Если Форма.Элементы.Свойства.ТекущаяСтрока = Неопределено Тогда
		Строка = Неопределено;
	Иначе
		Строка = Форма.Свойства.НайтиПоИдентификатору(Форма.Элементы.Свойства.ТекущаяСтрока);
	КонецЕсли;
	ТекущееСвойство = ?(Строка = Неопределено, Неопределено, Строка.Свойство);
	
	Форма.Свойства.Очистить();
	
	Если РезультатыЗапроса[1].Пустой() Тогда
		ТекущаяДоступность = Ложь;
		Возврат;
	КонецЕсли;
	
	Форма.ТекущийНаборВерсияДанных = РезультатыЗапроса[1].Выгрузить()[0].ВерсияДанных;
	
	РеквизитыСоЗначениямиСвойств = Новый Массив;
	Выборка = РезультатыЗапроса[0].Выбрать();
	Пока Выборка.Следующий() Цикл
		Если Выборка.ТипЗначения <> NULL
			И ТипЗначенияСодержитЗначенияСвойств(Выборка.ТипЗначения) Тогда
			Если ЗначениеЗаполнено(Выборка.ВладелецДополнительныхЗначений) Тогда
				РеквизитыСоЗначениямиСвойств.Добавить(Выборка.ВладелецДополнительныхЗначений);
			Иначе
				РеквизитыСоЗначениямиСвойств.Добавить(Выборка.Свойство);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("Владелец", РеквизитыСоЗначениямиСвойств);
	Запрос.Текст =
		"ВЫБРАТЬ
		|	ПРЕДСТАВЛЕНИЕ(ЗначенияСвойствОбъектов.Ссылка) КАК Наименование,
		|	ЗначенияСвойствОбъектов.Владелец КАК Владелец
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
		|ГДЕ
		|	ЗначенияСвойствОбъектов.Владелец В(&Владелец)
		|	И НЕ ЗначенияСвойствОбъектов.ЭтоГруппа
		|	И НЕ ЗначенияСвойствОбъектов.ПометкаУдаления
		|	И ЗначенияСвойствОбъектов.Ссылка В
		|			(ВЫБРАТЬ ПЕРВЫЕ 4
		|				ЗначенияСвойствОбъектовДляПроверки.Ссылка
		|			ИЗ
		|				Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектовДляПроверки
		|			ГДЕ
		|				ЗначенияСвойствОбъектовДляПроверки.Владелец = ЗначенияСвойствОбъектов.Владелец
		|				И НЕ ЗначенияСвойствОбъектовДляПроверки.ЭтоГруппа
		|				И НЕ ЗначенияСвойствОбъектовДляПроверки.ПометкаУдаления)
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ
		|	ПРЕДСТАВЛЕНИЕ(ЗначенияСвойствОбъектовИерархия.Ссылка) КАК Наименование,
		|	ЗначенияСвойствОбъектовИерархия.Владелец
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектовИерархия КАК ЗначенияСвойствОбъектовИерархия
		|ГДЕ
		|	ЗначенияСвойствОбъектовИерархия.Владелец В(&Владелец)
		|	И НЕ ЗначенияСвойствОбъектовИерархия.ПометкаУдаления
		|	И ЗначенияСвойствОбъектовИерархия.Ссылка В
		|			(ВЫБРАТЬ ПЕРВЫЕ 4
		|				ЗначенияСвойствОбъектовИерархияДляПроверки.Ссылка
		|			ИЗ
		|				Справочник.ЗначенияСвойствОбъектовИерархия КАК ЗначенияСвойствОбъектовИерархияДляПроверки
		|			ГДЕ
		|				ЗначенияСвойствОбъектовИерархияДляПроверки.Владелец = ЗначенияСвойствОбъектовИерархия.Владелец
		|				И НЕ ЗначенияСвойствОбъектовИерархияДляПроверки.ПометкаУдаления)
		|
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	ЗначенияСвойствОбъектов.Владелец КАК Владелец
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов
		|ГДЕ
		|	ЗначенияСвойствОбъектов.Владелец В(&Владелец)
		|	И НЕ ЗначенияСвойствОбъектов.ЭтоГруппа
		|
		|ОБЪЕДИНИТЬ ВСЕ
		|
		|ВЫБРАТЬ ПЕРВЫЕ 1
		|	ЗначенияСвойствОбъектовИерархия.Владелец КАК Владелец
		|ИЗ
		|	Справочник.ЗначенияСвойствОбъектовИерархия КАК ЗначенияСвойствОбъектовИерархия
		|ГДЕ
		|	ЗначенияСвойствОбъектовИерархия.Владелец В(&Владелец)";
	ВыборкаЗначений = Запрос.ВыполнитьПакет();
	
	Результат = ВыборкаЗначений[0].Выгрузить();
	СоответствиеЗначенийРеквизитов = Новый Соответствие;
	Для Каждого Строка Из Результат Цикл
		ТекущийСписокЗначений = СоответствиеЗначенийРеквизитов[Строка.Владелец];
		Если ТекущийСписокЗначений = Неопределено Тогда
			Индекс = 1;
			СоответствиеЗначенийРеквизитов.Вставить(Строка.Владелец, Строка.Наименование);
		Иначе
			Индекс = Индекс + 1;
			Если Индекс = 4 Тогда
				ТекущийСписокЗначений = ТекущийСписокЗначений + ",...";
			Иначе
				ТекущийСписокЗначений = ТекущийСписокЗначений + ", " + Строка.Наименование;
			КонецЕсли;
			СоответствиеЗначенийРеквизитов.Вставить(Строка.Владелец, ТекущийСписокЗначений);
		КонецЕсли;
	КонецЦикла;
	
	Результат = ВыборкаЗначений[1].Выгрузить();
	РеквизитыСоЗначениями = Новый Соответствие;
	Для Каждого Строка Из Результат Цикл
		РеквизитыСоЗначениями.Вставить(Строка.Владелец, Истина);
	КонецЦикла;
	
	Выборка = РезультатыЗапроса[0].Выбрать();
	Пока Выборка.Следующий() Цикл
		
		НоваяСтрока = Форма.Свойства.Добавить();
		ЗаполнитьЗначенияСвойств(НоваяСтрока, Выборка);
		
		НоваяСтрока.ОбщиеЗначения = ЗначениеЗаполнено(Выборка.ВладелецДополнительныхЗначений);
		
		Если Выборка.ТипЗначения <> NULL
		   И ТипЗначенияСодержитЗначенияСвойств(Выборка.ТипЗначения) Тогда
			
			НоваяСтрока.ТипЗначения = Строка(Новый ОписаниеТипов(
				Выборка.ТипЗначения,
				,
				"СправочникСсылка.ЗначенияСвойствОбъектовИерархия,
				|СправочникСсылка.ЗначенияСвойствОбъектов"));
			
			Если ЗначениеЗаполнено(Выборка.ВладелецДополнительныхЗначений) Тогда
				ПервыеЗначения = СоответствиеЗначенийРеквизитов[Выборка.ВладелецДополнительныхЗначений];
				ЕстьЗначения   = РеквизитыСоЗначениями[Выборка.ВладелецДополнительныхЗначений];
			Иначе
				ПервыеЗначения = СоответствиеЗначенийРеквизитов[Выборка.Свойство];
				ЕстьЗначения   = РеквизитыСоЗначениями[Выборка.Свойство];
			КонецЕсли;
			
			Если ПервыеЗначения = Неопределено Тогда 
				Если ЕстьЗначения = Истина Тогда
					ПредставлениеЗначений = НСтр("ru = 'Значения помечены на удаление'");
				Иначе
					ПредставлениеЗначений = НСтр("ru = 'Значения еще не введены'");
				КонецЕсли;
			Иначе
				ПредставлениеЗначений = ПервыеЗначения;
			КонецЕсли;
			ПредставлениеЗначений = "<" + ПредставлениеЗначений + ">";
			Если ЗначениеЗаполнено(НоваяСтрока.ТипЗначения) Тогда
				ПредставлениеЗначений = ПредставлениеЗначений + ", ";
			КонецЕсли;
			НоваяСтрока.ТипЗначения = ПредставлениеЗначений + НоваяСтрока.ТипЗначения;
		КонецЕсли;
		
		Если Выборка.Свойство = ТекущееСвойство Тогда
			Форма.Элементы.Свойства.ТекущаяСтрока =
				Форма.Свойства[Форма.Свойства.Количество()-1].ПолучитьИдентификатор();
		КонецЕсли;
	КонецЦикла
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// Обновление информационной базы.

// Заполняет обработчик разделенных данных, зависимый от изменения неразделенных данных.
//
// Параметры:
//   Параметры - Структура - структура параметров обработчиков:
//     * РазделенныеОбработчики - см. ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления
// 
Процедура ЗаполнитьОбработчикиРазделенныхДанных(Параметры = Неопределено) Экспорт
	
	Если Параметры <> Неопределено И ЕстьИзмененияПредставленийОбъектовМетаданныхСоСвойствами() Тогда
		Обработчики = Параметры.РазделенныеОбработчики;
		Обработчик = Обработчики.Добавить();
		Обработчик.Версия = "*";
		Обработчик.РежимВыполнения = "Оперативно";
		Обработчик.Процедура = "УправлениеСвойствамиСлужебный.СоздатьПредопределенныеНаборыСвойств";
	КонецЕсли;
	
КонецПроцедуры

// Устанавливает значения свойства Используется в значение Истина.
//
Процедура УстановитьЗначениеПризнакаИспользуется() Экспорт
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	НаборыДополнительныхРеквизитовИСведений.Ссылка
	|ИЗ
	|	Справочник.НаборыДополнительныхРеквизитовИСведений КАК НаборыДополнительныхРеквизитовИСведений
	|ГДЕ
	|	НЕ НаборыДополнительныхРеквизитовИСведений.Используется";
	
	Результат = Запрос.Выполнить();
	Выборка = Результат.Выбрать();
	
	Пока Выборка.Следующий() Цикл
		
		НачатьТранзакцию();
		Попытка
			Блокировка = Новый БлокировкаДанных;
			ЭлементБлокировки = Блокировка.Добавить("Справочник.НаборыДополнительныхРеквизитовИСведений");
			ЭлементБлокировки.УстановитьЗначение("Ссылка", Выборка.Ссылка);
			Блокировка.Заблокировать();
		
			НаборОбъект = Выборка.Ссылка.ПолучитьОбъект();
			НаборОбъект.Используется = Истина;
			ОбновлениеИнформационнойБазы.ЗаписатьДанные(НаборОбъект);
			
			ЗафиксироватьТранзакцию();
		Исключение
			ОтменитьТранзакцию();
			ВызватьИсключение;
		КонецПопытки;
		
	КонецЦикла;
	
КонецПроцедуры

Процедура ПеренестиНастройку(Настройка, КлючНазначения, ИмяНабора, УИДСтарогоНабора = Неопределено) Экспорт
	
	Если СтрНайти(Настройка.КлючОбъекта, КлючНазначения) = 0 Тогда
		Возврат;
	КонецЕсли;
	
	НовыйНабор = УправлениеСвойствами.НаборСвойствПоИмени(ИмяНабора);
	Если ТипЗнч(НовыйНабор) <> Тип("СправочникСсылка.НаборыДополнительныхРеквизитовИСведений") Тогда
		Возврат;
	КонецЕсли;
	
	ИдентификаторНовогоНабора = НовыйНабор.УникальныйИдентификатор();
	КонтрольнаяСумма = ОбщегоНазначения.КонтрольнаяСуммаСтрокой(СтрЗаменить(ИдентификаторНовогоНабора, "-", ""));
	НовыйКлючНазначения  = "КлючНаборовСвойств" + КонтрольнаяСумма;
	
	ЗначениеНастройки = ОбщегоНазначения.ХранилищеСистемныхНастроекЗагрузить(Настройка.КлючОбъекта,
		Настройка.КлючНастроек, , , Настройка.Пользователь);
	
	Если УИДСтарогоНабора <> Неопределено Тогда
		ИДСтарогоНабора = СтрЗаменить(ВРег(УИДСтарогоНабора), "-", "x");
		ИДНовогоНабора  = СтрЗаменить(ВРег(ИдентификаторНовогоНабора), "-", "x");
		ЗначениеНастройкиСтрокой = ЗначениеВСтрокуВнутр(ЗначениеНастройки);
		ЗначениеНастройкиСтрокой = СтрЗаменить(ЗначениеНастройкиСтрокой, ИДСтарогоНабора, ИДНовогоНабора);
		ЗначениеНастройки = ЗначениеИзСтрокиВнутр(ЗначениеНастройкиСтрокой);
	КонецЕсли;
	
	НовыйКлючОбъекта = СтрЗаменить(Настройка.КлючОбъекта, КлючНазначения, НовыйКлючНазначения);
	ОбщегоНазначения.ХранилищеСистемныхНастроекСохранить(НовыйКлючОбъекта, Настройка.КлючНастроек,
		ЗначениеНастройки, , Настройка.Пользователь);
	
КонецПроцедуры

// Параметры:
//  МенеджерНастроек - СтандартноеХранилищеНастроекМенеджер
//
Функция ЧтениеНастроекИзХранилища(МенеджерНастроек) Экспорт
	
	Настройки = Новый ТаблицаЗначений;
	Настройки.Колонки.Добавить("КлючОбъекта");
	Настройки.Колонки.Добавить("КлючНастроек");
	Настройки.Колонки.Добавить("Пользователь");
	
	ВыборкаНастроек = МенеджерНастроек.Выбрать();
	Пока СледующаяНастройка(ВыборкаНастроек) Цикл
		
		Если СтрНайти(ВыборкаНастроек.КлючОбъекта, "КлючНаборовСвойств") = 0 Тогда
			Продолжить;
		КонецЕсли;
		
		НоваяСтрока = Настройки.Добавить();
		НоваяСтрока.КлючОбъекта = ВыборкаНастроек.КлючОбъекта;
		НоваяСтрока.КлючНастроек = ВыборкаНастроек.КлючНастроек;
		НоваяСтрока.Пользователь = ВыборкаНастроек.Пользователь;
		
	КонецЦикла;
	
	Возврат Настройки;
	
КонецФункции

#КонецОбласти
